Saving C Binary search tree to txt file - c

I am doing a C BST library and im trying to do a function that will save the binary search tree into a text file.I am quite confuse on how to do it.Heres my tree structure:
struct Node {
int value;
struct Node *left;
struct Node *right;
};
typedef struct Node TNode;
typedef struct Node *binary_tree;
Creation of the tree:
binary_tree NewBinaryTree(int value_root) {
binary_tree newRoot = malloc(sizeof(TNode));
if (newRoot) {
newRoot->value = value_root;
newRoot->left = NULL;
newRoot->right = NULL;
}
return newRoot;
}
Adding elements to it:
void Insert(binary_tree *tree, int val) {
if (*tree == NULL) {
*tree = (binary_tree)malloc(sizeof(TNode));
(*tree)->value = val;
(*tree)->left = NULL;
(*tree)->right = NULL;
} else {
if (val < (*tree)->value) {
Insert(&(*tree)->left, val);
} else {
Insert(&(*tree)->right, val);
}
}
}
I did a start of the function but I dont know how to do this:
void savetree(binary_tree *tree, char * filename)
{
FILE *afile;
int remainn, counter, readsize, i;
int *bb;
afile = fopen(filename, "wb");
if (afile) {
bb = calloc(sizeof(int), BBSIZE); //BBSIZE =4096
remainn = treesize(tree);
counter = 0;
while (remainn > 0) {
if (remainn > BBSIZE) {
readsize = BBSIZE;
} else {
readsize = remainn;
}
Heres the treesize function:
int treesize( binary_tree tree )
{
if( tree == NULL )
{
return (0) ;
}
else
{
return( 1 + treesize( tree->left ) + treesize( tree->right ) ) ;
}
}
This savetree function is not completed but im not sure on how to complete it/if what I did is correct.
thank you

Nested parentheses and trees are alternative representations for the same thing.
So writing a tree is easy
void writenode(Node *node)
{
printf("{");
printf("%d ", node-.value);
if(node->left)
writenode(node->left);
if(node->right)
writenode(node->right);
printf("}");
}
Reading is quite a bit harder. You have to detect malformed input, and construct the children recursively.

The easiest way to save binary tree to a txt file is saving them as an array. Only downside is you will waste space because it will save the binary tree as complete binary tree.
It is easy to write and even to read. Because left, right child and parent of node at ith index can be found as:
int left(int i) {
return 2*i + 1;
}
int right(int i) {
return 2*i + 2;
}
int parent(int i) {
return (i-1)/2;
}

For a sparse binary tree(Binary tree which has rare nodes but height is very), One method is save its preorder and postorder traversals and then rebuild this binary tree from these two traversals to avoid saving many NULL bytes as suggested by Dulguun.
Some examples: Construct Full Binary Tree from given preorder and postorder traversals

Related

How can I check if two binary trees contain the same nodes?

I am trying the implement a function which checks whether two binary search trees are equal, order of the nodes not matter. But my implementation does not work.
I am not allowed to flatten the trees into arrays.
this is what I have so far:
int isIdentical(struct Node* root1, struct Node* root2)
{
if (root1 == NULL && root2 == NULL)
return 1;
else if (root1 == NULL || root2 == NULL)
return 0;
else {
if (root1->data == root2->data && isIdentical(root1->left, root2->left)
&& isIdentical(root1->right, root2->right))
return 1;
else
return 0;
}
}
when supplied with trees containing the nodes tree A = 2 4 5 6 and Tree B = 2 5 4 6, the output should be:
1, meaning they are equal, but instead I am getting 0. I am not sure where I am going wrong.
This is how Node is implemeted:
struct Node {
int data;
struct Node* left;
struct Node* right;
};
Make a recursive function that traverses treeA and checks that every item is present in treeB. On failure it abandons the search and returns 0 for failure. It can be your function
int isIdentical(struct Node* root1, struct Node* root2)
If success, call the function again with the arguments for treeA and treeB reversed. The 'check if present' operation can be iterative and inline, because it does not need to backtrack.
Example untried code, to give the idea.
int isAllFound(struct Node* root1, struct Node* root2)
{
// recursive parse of tree 1
if (root1 == NULL)
return 1;
// iterative search of tree 2
int found = 0;
struct Node *root = root2;
while(root != NULL) {
if(root1->data == root->data) {
found = 1;
break;
}
if(root1->data < root->data)
root = root->left;
else
root = root->right;
}
if(!found)
return 0;
// continue recursive parse of tree 1
if(!isAllFound(root1->left, root2))
return 0;
if(!isAllFound(root1->right, root2))
return 0;
return 1;
}
Then call like
if(isAllFound(treeA, treeB) && isAllFound(treeB, treeA))
puts("Success!");
If every item of treeA can be found in treeB, and every item of treeB can be found in treeA then they contain the same data. Provided the keys are unique.
Why do you think they are equal? They are not.
tree A is represented as 2 4 5 6 which I guess you obtained by some sort of pre-order or level-order traversal. If your tree B (2, 5, 4, 6) is equal then with the same sort of traversal you'd obtain same order. They are not equal if the traversal is the same.
Order of nodes doesn't matter:
If the order of the nodes doesn't matter. One thing you could do is do an inorder traversal for both trees and you get a sorted array from both. Then compare both arrays element by element and declare equal or not.
Your function will only compare as equal 2 trees that have exactly the same structure. If the trees are balanced differently, the comparison will return 0 even if the values are identical.
Performing this comparison is non trivial as the trees can have an arbitrary depth if they are not balanced.
You can walk the first tree in depth first order to populate an array and then walk the second tree in depth first order, checking that the values are identical to those in the array.
Here is a simple implementation:
#include <stdlib.h>
struct Node {
int data;
struct Node* left;
struct Node* right;
};
size_t tree_length(const struct Node *root) {
return root ? 1 + tree_length(root->left) + tree_length(root->right) : 0;
}
void tree_store(int *array, size_t *pos, struct Node *node) {
if (node) {
tree_store(array, pos, node->left);
array[++*pos - 1] = node->data;
tree_store(array, pos, node->right);
}
}
int tree_check(int *array, size_t *pos, struct Node *node) {
if (node) {
return tree_check(array, pos, node->left)
&& array[++*pos - 1] == node->data
&& tree_check(array, pos, node->right);
} else {
return 1;
}
}
/* compare trees: return 0 if different, 1 if same values, -1 if allocation error */
int isIdentical(const struct Node *root1, const struct Node *root2) {
size_t len1 = tree_length(root1);
size_t len2 = tree_length(root2);
size_t pos;
if (len1 != len2)
return 0;
if (len1 == 0)
return 1;
int *array = malloc(sizeof(*array) * len1);
if (!array)
return -1;
pos = 0;
tree_store(array, &pos, root1);
pos = 0;
int res = tree_check(array, &pos, root2);
free(array);
return res;
}
If you are not allowed to convert the trees to arrays, you could:
normalize both trees, then use your simple comparator, but this will modify the trees and is difficult.
implement a stack based iterator and iterate both trees in parallel.
Here is a simple implementation of the latter:
#include <stddef.h>
struct Node {
int data;
struct Node *left;
struct Node *right;
};
size_t max_size(size_t a, size_t b) {
return a < b ? b : a;
}
size_t tree_depth(const struct Node *root) {
return root ? 1 + max_size(tree_depth(root->left), tree_depth(root->right)) : 0;
}
int tree_next(const struct Node **stack, size_t *ppos, int *value) {
size_t pos = *ppos;
if (stack[pos] == NULL) {
if (pos == 0)
return 0; // no more values
pos--;
} else {
while (stack[pos]->left) {
stack[pos + 1] = stack[pos]->left;
pos++;
}
}
*value = stack[pos]->data;
stack[pos] = stack[pos]->right;
*ppos = pos;
return 1;
}
/* compare trees: return 0 if different, 1 if same values, -1 if allocation error */
int isIdentical(const struct Node *root1, const struct Node *root2) {
if (root1 == NULL || root2 == NULL)
return root1 == root2;
size_t depth1 = tree_depth(root1);
size_t depth2 = tree_depth(root2);
const struct Node *stack1[depth1];
const struct Node *stack2[depth2];
size_t pos1 = 0;
size_t pos2 = 0;
stack1[pos1++] = root1;
stack2[pos2++] = root2;
for (;;) {
int value1, value2;
int has1 = tree_next(stack1, &pos1, &value1);
int has2 = tree_next(stack2, &pos2, &value2);
if (!has1 && !has2)
return 1;
if (!has1 || !has2 || value1 != value2)
return 0;
}
}

How to get entire contents of binary tree in array form?

I have a C structure that represents a binary tree:
struct btree {
char *word;
int frequency;
struct btree *left;
struct btree *right;
};
I want to create a function btree_list(struct btree*) that returns an array of all the btree objects in the binary tree passed to it. Order does not matter.
Here is an example of how this function would work:
struct btree *T = populate_with_random_values();
struct btree *entries = (struct btree*) malloc(sizeof(struct btree) * btree_size(T));
entries = btree_list(T);
while (*entries != NULL) {
printf("There are %d occurences of the word %s", entries->frequency, entries->word);
entries++;
}
Also for each element E in entries, E->left and E->right should be set to NULL since they aren't technically being used. How would I go about implementing this?
This could be the array:
typedef struct {
struct btree **data;
size_t count;
} t_tbl;
t_tbl *tbl_create(size_t count)
{
t_tbl *new = NULL;
if (count > 0) {
new = malloc(sizeof(t_tbl));
new->data = malloc(count * sizeof(struct btree *));
new->count = 0;
}
return new;
}
void tbl_destroy(t_tbl *table)
{
if (table) {
free(table->data);
free(table);
}
}
And this could be the process:
void btree_populate_array(const t_node *root, t_tbl *table)
{
if (root->left) btree_populate_array(root->left, table);
table->data[table->count++] = root;
if (root->right) btree_populate_array(root->right, table);
}
if (root) {
t_tbl *table = tbl_create(btree_size);
btree_populate_array(root, table);
/* Do stuff with array */
tbl_destroy(table);
}
You have to check malloc, if you don't know the size of btree:
void btree_count(const t_node *root, size_t *count)
{
if (root->left) btree_count(root->left, count);
(*count)++;
if (root->right) btree_count(root->right, count);
}
size_t btree_size = 0;
if (root) {
btree_count(root, &btree_size);
}
Rather than returning the array just pass its base address to make your life easier and return the count of your array:
int TraverseTree(int arr[],btreenode *root, int depth)
{
static int count = 0;
if (root)
{
count++;
TraverseTree(arr,root->right,depth+1);
arr[depth]=root->data;
TraverseTree(arr,root->left, depth+1);
}
return count;
}
Well, do you want a preorder, inorder, or postorder traversal?
Here's a preorder example in pseudocode: (credit to Wikipedia)
iterativePreorder(node)
parentStack = empty stack
while not parentStack.isEmpty() or node ≠ null
if node ≠ null then
visit(node)
if node.right ≠ null then
parentStack.push(node.right)
node = node.left
else
node = parentStack.pop()
You'll have to tweak this a bit in order to get it to return a list of the nodes, but the idea behind walking the tree is all there.

insertion binary search tree in C

I've been stuck on the insertion part of the binary search tree. I get so confused with nested structs. The basic idea of this program is to create a bst that is able to hold names and double values which get stored by value (obviously).
Example: I want to store
Jane 3.14
John 3.233
Luke 6.4
Mike 1.4
so the bst would look like
3.14
/ \
1.4 3.233
\
6.4
however I'm having trouble with the insertHelper recursion portion of the code. The hash table is a bonus part of the code that I'll try implementing at a later time. Thank you for your help!
typedef struct name_val // holds name and value
{
char *name;
double value;
}NAME_VAL;
typedef struct node //binary search tree
{
NAME_VAL *nV;
struct node *left;
struct node *right;
}NODE;
struct tmap_struct //handle for bst and hashtable
{
int nL; //nodes on left
int nR; //nodes on right
NODE *root;
NODE **table;
};
int tmap_insert(TMAP_PTR hashTree, char * name, double val)
{
if(hashTree->root == NULL)
{
NODE *bst = (NODE *)malloc(sizeof(NODE));
NAME_VAL *root = (NAME_VAL *)malloc(sizeof(NAME_VAL));
bst->nV = root;
bst->nV->value = val;
strcpy(bst->nV->name, name);
hashTree->root = bst;
hashTree->nL = 0;
hashTree->nR = 0;
}
else
insertHelper(hashTree->root, val, name);
}
void insertHelper(TMAP_PTR hashTree, int val, char * name)
{
if(val < hashTree->root->nV->value)
{
if(hashTree->root->left == NULL)
{
hashTree->root->left = (NODE *)malloc(sizeof(NODE));
hashTree->root->left->nV = (NAME_VAL *) malloc(sizeof(NAME_VAL));
strcpy(hashTree->root->left->nV->name, name);
hashTree->root->nV->value = val;
(hashTree->nL)++;
}
else
insertHelper(hashTree->root->left, val, name);
}
else
{
if(hashTree->root->right == NULL)
{
hashTree->root->right = (NODE *)malloc(sizeof(NODE));
hashTree->root->right->nV = (NAME_VAL *)malloc(sizeof(NAME_VAL));
strcpy(hashTree->root->left->nV->name,name);
hashTree->root->nV->value = val;
(hashTree->nR)++;
}
else
insertHelper(hashTree->root->right, val, name);
}
}
I doubt this compiles. Is that the problem you're having?
From what I can see, you have declared insertHelper with the wrong type for its first parameter. It should take NODE* values, not TMAP_PTR values. That's because you always call it with nodes out of your tree.
So the first part of the function should look like this:
void insertHelper(NODE *node, int val, char * name)
{
if(val < node->nV->value)
{
if(node->left == NULL)
{
node->left = (NODE *)malloc(sizeof(NODE));
node->left->nV = (NAME_VAL *) malloc(sizeof(NAME_VAL));
strcpy(node->left->nV->name, name);
node->left->nV->value = val;
}
else
insertHelper(node->left, val, name);
}
//.....
Note that I removed the line:
(hashTree->nR)++;
It hardly even makes sense to track this information, unless maybe you do it at the node level.
But if you must, you could have insertHelper recursively return a positive or negative value to indicate what side it inserted on. But that doesn't makes sense. What is it on the right of? You may have inserted it on the right of a node that was in the left half of the tree.
If you store this information on each node, you can recursively update the node above as you return from insertHelper. Maybe that's what you were trying to do. Balanced tree implementations do something similar - AVL trees store the maximum depth of the tree at a node and use that to do branch rotations for rebalancing.
You'll have to adapt mine(It's almost standard C besides the unneeded template and class), but it's a similar algorithm: (I believe, I didn't look at any source for my own purposes.)
template<typename T>
class BST {
protected:
typedef struct node_t {
struct node_t * dir[2];
T data;
} node;
node * root;
void insert_node(node * active_node, T data){ //call with node *root;
int next = data < active_node->data ? 0 : 1;
if(active_node->dir[next] == NULL){
active_node->dir[next] = new node;
active_node->dir[next]->dir[0] = NULL;
active_node->dir[next]->dir[1] = NULL;
active_node->data = data;
} else
insert_node(active_node->dir[next], data);
}
public:
BST() : root(new node){root->dir[0] = NULL; root->dir[1] = NULL; root->data = 0;}
~BST(){}
}

Iterative deepening depth-first search in binary tree

i am having a normal binary tree that i am trying to apply iterative deepening depth first search on using c :
struct node {
int data;
struct node * right;
struct node * left;
};
typedef struct node node;
and i am using a function to insert nodes into tree, now i need to implement the search function to be something like this:
function search(root,goal,maxLevel)
so it search using depth first search but to a specific max level then stop
that was my first try,it doesn't work :
currentLevel = 0;
void search(node ** tree, int val, int depth)
{
if(currentLevel <= depth) {
currentLevel++;
if((*tree)->data == val)
{
printf("found , current level = %i , depth = %i", currentLevel,depth);
} else if((*tree)->left!= NULL && (*tree)->right!= NULL)
{
search(&(*tree)->left, val, depth);
search(&(*tree)->right, val, depth);
}
}
}
please help, thanks ...
You never stop...
node *search(node ** tree, int val, int depth)
{
if (depth <= 0)
{
return NULL; // not found
}
if((*tree)->data == val)
{
return *tree;
}
if((*tree)->left)
{
node * left = search(&(*tree)->left, val, depth - 1);
if (left) return left; // found
}
if((*tree)->right)
{
node * right = search(&(*tree)->left, val, depth - 1);
return right; // whatever is result of right
}
return NULL; // not found
}
The global variable won't work for this. You want to have something like
void search(node ** tree, int val, int remainingDepth) {
if (remainingDepth == 0) return;
then
search(&(*tree)->left, val, remainingDepth - 1);
search(&(*tree)->right, val, remainingDepth - 1);
You probably also want to check left & right for null separately, as each could be independently null.

Creating a binary search tree in C99

I've got a programming class assignment due tonight at 8 PM CDT that I'm having trouble with. We are to take a list of the following numbers via reading a file:
9
30
20
40
35
22
48
36
37
38
place them in an array (easy enough), and then read these into a binary search tree using C. The first number in the list is the number of elements in the tree. The rest are placed into the following struct:
typedef struct node_struct {
int data;
struct node_struct* left;
struct node_struct* right;
} Node;
I think I've got the first part down pat. Take the stuff in using fscanf (I didn't choose to use this method, I like fgets better), call an insertion function on each member of the array, then call a "createNode" function inside the insertion function.
Problem is, I'm only getting one member into the BST. Furthermore, the BST must satisfy the condition node->left->data <= node->data < node->right->data... in other words, the nodes must be in order in the tree.
Here's what I have so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// def BST node struct
typedef struct node_struct {
int data;
struct node_struct* left;
struct node_struct* right;
} Node;
// prototypes
Node* createNode(int data);
Node* bstInsert(Node* root, int data);
// helper function prototypes
void padding(char ch, int n);
void displayTree(Node* root, int depth);
int main(int argc, char **argv)
{
FILE *in = NULL;
int num_read, count=0, array_size = 0;
if(argc != 2){
printf("hw3 <input-file>\n");
return 1;
}
in = fopen(argv[1], "r");
if(in == NULL){
printf("File can not be opened.\n");
return 2;
}
// read in the first line to get the array size
fscanf(in, "%d", &array_size);
// declare the array
int array[array_size];
// read from the second line to get each element of the array
while(!feof(in)){
fscanf(in, "%d", &num_read);
array[count] = num_read;
count++;
}
fclose(in);
if (array_size != count) {
printf("data error. Make sure the first line specifies the correct number of elements.");
return 3;
}
Node *root1 = NULL, *root2 = NULL, *root3 = NULL;
int i;
// task1: construct a bst from the unsorted array
printf("=== task1: construct a bst from the unsorted array ===\n");
for (i = 0; i < array_size; i++) {
root1 = bstInsert(root1, array[i]);
}
displayTree(root1, 0);
return 0;
}
Node* bstInsert(Node* root, int data) {
if(root == NULL){
root = createNode(data);
if(root != NULL){
root= createNode(data);
}
else{
printf("%d not inserted, no memory available.\n", data);
}
}
Node* current, previous, right;
current = root;
previous = root->left;
next = root->right;
else{
if(previous->data <= current->data){
}
}
return root;
}
Node* createNode(int data) {
// TODO
Node* aRoot;
if(!data)
return NULL;
aRoot = malloc(sizeof(Node));
if(!aRoot){
printf("Unable to allocate memory for node.\n");
return NULL;
}
aRoot->data = data;
aRoot->left = NULL;
aRoot->right = NULL;
return aRoot;
}
/* helper functions to print a bst; You just need to call displayTree when visualizing a bst */
void padding(char ch, int n)
{
int i;
for (i = 0; i < n; i++)
printf("%c%c%c%c", ch, ch ,ch, ch);
}
void displayTree(Node* root, int depth){
if (root == NULL) {
padding (' ', depth);
printf("-\n");
}
else {
displayTree(root->right, depth+1);
padding(' ', depth);
printf ( "%d\n", root->data);
displayTree(root->left, depth+1);
}
}
main, createNode, displayTree, and padding are okay, I believe. It's bstInsert where I'm having trouble. I'm just not sure how to order things to create a valid tree.
EDIT:
I've edited bstInsert and injected some more logic. It should be printing out more leaves on the tree, but alas, it's only printing out the number "30". Here's the new function.
Node* bstInsert(Node* root, int data) {
if(root == NULL){
root = createNode(data);
if(root != NULL){
root= createNode(data);
}
else{
printf("%d not inserted, no memory available.\n", data);
}
}
else{
if(data < root->data){
bstInsert(root->left, data);
}
else if(data > root->data || data == root->data){
bstInsert(root->right, data);
}
}
return root;
}
You have to assign the newly created node pointer to the correct part of the tree. This code does that. The key change is using the return value from bstInsert() correctly. The other changes are cosmetic. Note that I checked the input array by printing it out; also, it is sensible to print out the BST as you build it.
Don't use feof() as a loop control condition. It is almost invariably wrong when used as a loop control, but at least you have to also check the input operation that follows. I've written a lot of programs in my time; I've hardly ever used feof() (I found two places in my own code with it; in both, it was correctly used to distinguish between EOF and an error after an input had failed.)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// def BST node struct
typedef struct node_struct
{
int data;
struct node_struct* left;
struct node_struct* right;
} Node;
// prototypes
Node *createNode(int data);
Node *bstInsert(Node *root, int data);
// helper function prototypes
void padding(char ch, int n);
void displayTree(Node *root, int depth);
int main(int argc, char **argv)
{
FILE *in = NULL;
int num_read, count=0, array_size = 0;
if (argc != 2)
{
printf("hw3 <input-file>\n");
return 1;
}
in = fopen(argv[1], "r");
if (in == NULL)
{
printf("File can not be opened.\n");
return 2;
}
// read in the first line to get the array size
fscanf(in, "%d", &array_size);
// declare the array
int array[array_size];
// read from the second line to get each element of the array
while (count < array_size && fscanf(in, "%d", &num_read) == 1)
array[count++] = num_read;
fclose(in);
if (array_size != count)
{
printf("data error. Make sure the first line specifies the correct number of elements.");
return 3;
}
for (int i = 0; i < array_size; i++)
printf("%d: %d\n", i, array[i]);
Node *root1 = NULL;
// task1: construct a bst from the unsorted array
printf("=== task1: construct a bst from the unsorted array ===\n");
for (int i = 0; i < array_size; i++)
{
root1 = bstInsert(root1, array[i]);
displayTree(root1, 0);
}
displayTree(root1, 0);
return 0;
}
Node *bstInsert(Node *root, int data)
{
if (root == NULL)
{
root = createNode(data);
if (root == NULL)
printf("%d not inserted, no memory available.\n", data);
}
else if (data < root->data)
root->left = bstInsert(root->left, data);
else
root->right = bstInsert(root->right, data);
return root;
}
Node *createNode(int data)
{
Node *aRoot;
aRoot = malloc(sizeof(Node));
if (!aRoot)
{
printf("Unable to allocate memory for node.\n");
return NULL;
}
aRoot->data = data;
aRoot->left = NULL;
aRoot->right = NULL;
return aRoot;
}
/* helper functions to print a bst; You just need to call displayTree when visualizing a bst */
void padding(char ch, int n)
{
for (int i = 0; i < n; i++)
printf("%c%c%c%c", ch, ch, ch, ch);
}
void displayTree(Node *root, int depth)
{
if (root == NULL) {
padding (' ', depth);
printf("-\n");
}
else {
displayTree(root->right, depth+1);
padding(' ', depth);
printf ( "%d\n", root->data);
displayTree(root->left, depth+1);
}
}
Ok, think about what you want to do in the different tree configurations:
when the tree is empty -> create a root node
when the tree isn't empty -> how do the value to be inserted and the value of the root compare?
above -> insert in the right subtree
below -> insert in the left subtree
equal -> do nothing (this actually depends on how your assignment tells you to treat duplicates)
From this basic algorithm, you should be able to figure out all the corner cases.
A simplified solution (naive insertion with recursion, data input noise removed):
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
static int nums[] = { 6, 8, 4, 1, 3, 7, 14, 10, 13 }; // instead of the user input
typedef struct _node {
int value;
struct _node *left;
struct _node *right;
} node;
node *node_new(int v)
{
node *n = malloc(sizeof(*n));
assert(n);
n->value = v;
n->left = NULL;
n->right = NULL;
return n;
}
void insert(node **tree, node *leaf)
{
if (*tree == NULL) {
*tree = leaf;
} else if (leaf->value > (*tree)->value) {
insert(&((*tree)->right), leaf);
} else {
insert(&((*tree)->left), leaf);
}
}
void dump(node *tree, int level)
{
static const char *pad = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
if (tree != NULL) {
printf("%sSelf: %d\n", pad + 16 - level, tree->value);
if (tree->left) {
printf("%sLeft node:\n", pad + 16 - level);
dump(tree->left, level + 1);
}
if (tree->right) {
printf("%sRight node:\n", pad + 16 - level);
dump(tree->right, level + 1);
}
} else {
printf("%sEmpty\n", pad + 16 - level);
}
}
int main()
{
size_t n = sizeof(nums) / sizeof(*nums);
int i;
node *tree = NULL;
for (i = 0; i < n; i++) {
insert(&tree, node_new(nums[i]));
}
dump(tree, 0);
// give some work to the kernel
return 0;
}
You should consider doing this recursively. Remember that each node is a tree in itself:
#include <stdio.h>
#include <stdlib.h>
typedef struct tree_struct {
int value;
struct tree_struct* left;
struct tree_struct* right;
} Tree;
Tree* addToTree(int value, Tree* tree)
{
if (tree == NULL) {
tree = malloc(sizeof(Tree));
tree->value = value;
tree->left = NULL;
tree->right = NULL;
} else {
if (value < tree->value) {
tree->left = addToTree(value, tree->left);
} else {
tree->right = addToTree(value, tree->right);
}
}
return tree;
}
int main(int argc, char** argv)
{
Tree* tree = NULL;
int in;
while (scanf("%d", &in) != EOF) {
tree = addToTree(in, tree);
}
return 0;
}

Resources