BFS Traversal of a Binary Tree in C - c

While I know there are cleaner more efficient programs out there for BFS traversal in other languages, in c it gets a bit lengthy
I've found some really lengthy and complicated programs on leetcode, as a beginner those are a little hard to understand, while I understand the basic concept behind it I found a much simpler and cleaner code here sanfoundry
but it doesn't work for some reason? I'd be grateful if someone can help me out with this :)
#include <stdio.h>
#include <stdlib.h>
struct btnode
{
int value;
struct btnode *left, *right;
};
typedef struct btnode node;
/* function declarations */
void insert(node *, node *);
void bfs_traverse(node *);
/*global declarations */
node *root = NULL;
int val, front = 0, rear = -1, i;
int queue[20];
void main()
{
node *new = NULL ;
int num = 1;
printf("Enter the elements of the tree(enter 0 to exit)\n");
while (1)
{
scanf("%d", &num);
if (num == 0)
break;
new = malloc(sizeof(node));
new->left = new->right = NULL;
new->value = num;
if (root == NULL)
root = new;
else
{
insert(new, root);
}
}
printf("elements in a tree in inorder are\n");
queue[++rear] = root->value;
bfs_traverse(root);
for (i = 0;i <= rear;i++)
printf("%d -> ", queue[i]);
printf("%d\n", root->right->right->right->value);
}
/* inserting nodes of a tree */
void insert(node * new , node *root)
{
if (new->value>root->value)
{
if (root->right == NULL)
root->right = new;
else
insert (new, root->right);
}
if (new->value < root->value)
{
if (root->left == NULL)
root->left = new;
else
insert (new, root->left);
}
}
/* displaying elements using BFS traversal */
void bfs_traverse(node *root)
{
val = root->value;
if ((front <= rear)&&(root->value == queue[front]))
{
if (root->left != NULL)
queue[++rear] = root->left->value;
if (root->right != NULL || root->right == NULL)
queue[++rear] = root->right->value;
front++;
}
if (root->left != NULL)
{
bfs_traverse(root->left);
}
if (root->right != NULL)
{
bfs_traverse(root->right);
}
}

I suggest implementing a queue of type btnode *
btnode *queue[20]; // I assume 20 is enought for what you need
...
void bfs_traverse(node *root) {
val = root->val;
if (front <= rear)
{
if (root->left != NULL)
queue[++rear] = root->left;
if (root->right != NULL)
queue[++rear] = root->right;
bfs_traverse(queue[front++]);
}
}
However, I would rather implement it using while. It's much cleaner than a recursive function. I would use recursiveness for DFS

Related

how to enter in binary search tree by using command line

I am student and I am beginner at C.
I want to make binary search tree by using command line.
I want to enter the number composing BTS by using command line.
I have to make it by using pointer and print it by using preorder.
I delete some code because it's too much code in this question.(delete part)
how to make it?
I can't know how to make main part.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data; //정수를 보관할 노드
struct node *left_child; // 왼쪽 자식
struct node *right_child; // 오른쪽 자식
};
struct node* search(struct node *root, int x)
{
if (root=NULL || root->data==x) // root가 없거나 data가 root와 같다면 root를 리턴
return root;
else if (x > root->data)
return search(root->right_child, x);
else
return search(root->left_child, x);
}
struct node* find_minimum(struct node *root)
{
if(root==NULL)
return NULL;
else if(root->left_child != NULL)
return find_minimum(root->left_child);
return root;
}
struct node* new_node(int x)
{
struct node *p;
p = malloc(sizeof(struct node));
p->data = x;
p->left_child = NULL;
p->right_child = NULL;
return p;
}
struct node* insert(struct node *root, int x)
{
if(root==NULL)
return new_node(x);
else if(x<root->data)
root->left_child = insert(root->left_child,x);
else
root->right_child = insert(root->right_child, x);
return root;
}
void preorder(struct node *root)
{
if(root!=NULL)
{
printf("%d", root->data);
preorder(root->left_child);
preorder(root->right_child);
}
}
int main()
{
struct node *root;
int number;
int num_count = 0;
while(1)
{
scanf("%d", &number);
printf("%d", &number);
if (num_count = 0)
{
root = new_node(number);
num_count += 1;
}
else
if(number == EOF)
{
break;
}
else
{
insert(root, number);
}
}
preorder(root);
return 0;
}
There are multiple problems in your code:
The test if (root=NULL || root->data==x) is incorrect: = is the assignment operator, very different from the comparison operator ==. Use if (root == NULL || root->data == x)
&number is the address of variable number. Passing the address is required for scanf() to store the converted value into the destination object, but you should just pass the value to printf, without the & operator.
scanf() returns the number of successful conversions. Testing if (number == EOF) is surprising, you should test if (scanf("%d", &number) != 1) and possibly if (number < 0) if entering a negative number means end of input.
printf("%d", root->data); outputs just the digits, without any extra space or newline, causing all output to appear as a single string of digits. Add spaces and newlines to make the output more readable.
there is no need to special case the first node: initializing root as NULL and using root = insert(root, number); for each node is safer as it allows for an empty tree.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data; //정수를 보관할 노드
struct node *left_child; // 왼쪽 자식
struct node *right_child; // 오른쪽 자식
};
struct node *search(struct node *root, int x) {
if (root == NULL || root->data == x) // root가 없거나 data가 root와 같다면 root를 리턴
return root;
else
if (x > root->data)
return search(root->right_child, x);
else
return search(root->left_child, x);
}
struct node *find_minimum(struct node *root) {
if (root != NULL && root->left_child != NULL)
return find_minimum(root->left_child);
else
return root;
}
struct node *new_node(int x) {
struct node *p = malloc(sizeof(struct node));
if (p != NULL) {
p->data = x;
p->left_child = NULL;
p->right_child = NULL;
}
return p;
}
struct node *insert(struct node *root, int x) {
if (root == NULL)
return new_node(x);
else if (x < root->data)
root->left_child = insert(root->left_child, x);
else
root->right_child = insert(root->right_child, x);
return root;
}
void preorder(struct node *root) {
if (root != NULL) {
printf("%d ", root->data);
preorder(root->left_child);
preorder(root->right_child);
}
}
void free_tree(struct node *root) {
if (root != NULL) {
free_tree(root->left_child);
free_tree(root->right_child);
free(root);
}
}
int main() {
struct node *root = NULL;
int number;
while (scanf("%d", &number) == 1 && number >= 0) {
printf("%d\n", number);
root = insert(root, number);
}
preorder(root);
printf("\n");
free_tree(root);
return 0;
}

Test or verify properties of red-black tree

I have based this code on the Wikipedia article about red-black trees and on the part about red-black trees in the CLRS book "Introduction to Algorithms". This program displays the expected results if I run it. Now I would like to verify that it is good. How can one verify the properties and not just simply test it for certain cases? I would like to verify that the code fulfills the specification. I suppose that I could write a test case building up a large red-black tree and then deallocating it but that is still only a test and not a complete verification.
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
static char BLACK = 'b';
static char RED = 'r';
struct node {
int key;
char color;
struct node *left, *right, *parent;
};
void insert_repair_tree(struct node* n);
void delete_case1(struct node* n);
void delete_case2(struct node* n);
void delete_case3(struct node* n);
void delete_case4(struct node* n);
void delete_case5(struct node* n);
struct node *LEAF;
struct node *parent(struct node *n) {
return n->parent; // NULL for root node
}
struct node *grandparent(struct node *n) {
struct node *p = parent(n);
if (p == NULL)
return NULL; // No parent means no grandparent
return parent(p); // NULL if parent is root
}
struct node *sibling(struct node *n) {
struct node *p = parent(n);
if (p == NULL)
return NULL; // No parent means no sibling
if (n == p->left)
return p->right;
else
return p->left;
}
struct node *uncle(struct node *n) {
struct node *p = parent(n);
struct node *g = grandparent(n);
if (g == NULL)
return NULL; // No grandparent means no uncle
return sibling(p);
}
void rotate_left(struct node *n) {
struct node *nnew = n->right;
struct node *p = parent(n);
assert(nnew != NULL); // since the leaves of a red-black tree are empty, they cannot become internal nodes
n->right = nnew->left;
nnew->left = n;
n->parent = nnew;
// handle other child/parent pointers
if (n->right != NULL)
n->right->parent = n;
if (p != NULL) // initially n could be the root
{
if (n == p->left)
p->left = nnew;
else if (n == p->right) // if (...) is excessive
p->right = nnew;
}
nnew->parent = p;
}
void rotate_right(struct node *n) {
struct node *nnew = n->left;
struct node *p = parent(n);
assert(nnew != NULL); // since the leaves of a red-black tree are empty, they cannot become internal nodes
n->left = nnew->right;
nnew->right = n;
n->parent = nnew;
// handle other child/parent pointers
if (n->left != NULL)
n->left->parent = n;
if (p != NULL) // initially n could be the root
{
if (n == p->left)
p->left = nnew;
else if (n == p->right) // if (...) is excessive
p->right = nnew;
}
nnew->parent = p;
}
void insert_recurse(struct node* root, struct node* n) {
// recursively descend the tree until a leaf is found
if (root != NULL && n->key < root->key) {
if (root->left != LEAF) {
insert_recurse(root->left, n);
return;
}
else
root->left = n;
} else if (root != NULL) {
if (root->right != LEAF){
insert_recurse(root->right, n);
return;
}
else
root->right = n;
}
// insert new node n
n->parent = root;
n->left = LEAF;
n->right = LEAF;
n->color = RED;
}
void insert_case1(struct node* n)
{
if (parent(n) == NULL)
n->color = BLACK;
}
void insert_case2(struct node* n)
{
return; /* Do nothing since tree is still valid */
}
void insert_case3(struct node* n)
{
parent(n)->color = BLACK;
uncle(n)->color = BLACK;
grandparent(n)->color = RED;
insert_repair_tree(grandparent(n));
}
void insert_case4step2(struct node* n)
{
struct node* p = parent(n);
struct node* g = grandparent(n);
if (n == p->left)
rotate_right(g);
else
rotate_left(g);
p->color = BLACK;
g->color = RED;
}
void insert_case4(struct node* n)
{
struct node* p = parent(n);
struct node* g = grandparent(n);
if (n == g->left->right) {
rotate_left(p);
n = n->left;
} else if (n == g->right->left) {
rotate_right(p);
n = n->right;
}
insert_case4step2(n);
}
void insert_repair_tree(struct node* n) {
if (parent(n) == NULL) {
insert_case1(n);
} else if (parent(n)->color == BLACK) {
insert_case2(n);
} else if (uncle(n)->color == RED) {
insert_case3(n);
} else {
insert_case4(n);
}
}
struct node *insert(struct node* root, struct node* n) {
// insert new node into the current tree
insert_recurse(root, n);
// repair the tree in case any of the red-black properties have been violated
insert_repair_tree(n);
// find the new root to return
root = n;
while (parent(root) != NULL)
root = parent(root);
return root;
}
void replace_node(struct node* n, struct node* child){
child->parent = n->parent;
if (n == n->parent->left)
n->parent->left = child;
else
n->parent->right = child;
}
int is_leaf(struct node* n){
if(n->right ==NULL && n->left == NULL)
return 1;
else return 0;
}
void delete_one_child(struct node* n)
{
/*
* Precondition: n has at most one non-leaf child.
*/
struct node* child = is_leaf(n->right) ? n->left : n->right;
replace_node(n, child);
if (n->color == BLACK) {
if (child->color == RED)
child->color = BLACK;
else
delete_case1(child);
}
free(n);
}
void delete_case1(struct node* n)
{
if (n->parent != NULL)
delete_case2(n);
}
void delete_case2(struct node* n)
{
struct node* s = sibling(n);
if (s->color == RED) {
n->parent->color = RED;
s->color = BLACK;
if (n == n->parent->left)
rotate_left(n->parent);
else
rotate_right(n->parent);
}
delete_case3(n);
}
void delete_case3(struct node* n)
{
struct node* s = sibling(n);
if ((n->parent->color == BLACK) &&
(s->color == BLACK) &&
(s->left->color == BLACK) &&
(s->right->color == BLACK)) {
s->color = RED;
delete_case1(n->parent);
} else
delete_case4(n);
}
void delete_case4(struct node* n)
{
struct node* s = sibling(n);
if ((n->parent->color == RED) &&
(s->color == BLACK) &&
(s->left->color == BLACK) &&
(s->right->color == BLACK)) {
s->color = RED;
n->parent->color = BLACK;
} else
delete_case5(n);
}
void delete_case6(struct node* n)
{
struct node* s = sibling(n);
s->color = n->parent->color;
n->parent->color = BLACK;
if (n == n->parent->left) {
s->right->color = BLACK;
rotate_left(n->parent);
} else {
s->left->color = BLACK;
rotate_right(n->parent);
}
}
void delete_case5(struct node* n)
{
struct node* s = sibling(n);
if (s->color == BLACK) { /* this if statement is trivial,
due to case 2 (even though case 2 changed the sibling to a sibling's child,
the sibling's child can't be red, since no red parent can have a red child). */
/* the following statements just force the red to be on the left of the left of the parent,
or right of the right, so case six will rotate correctly. */
if ((n == n->parent->left) &&
(s->right->color == BLACK) &&
(s->left->color == RED)) { /* this last test is trivial too due to cases 2-4. */
s->color = RED;
s->left->color = BLACK;
rotate_right(s);
} else if ((n == n->parent->right) &&
(s->left->color == BLACK) &&
(s->right->color == RED)) {/* this last test is trivial too due to cases 2-4. */
s->color = RED;
s->right->color = BLACK;
rotate_left(s);
}
}
delete_case6(n);
}
struct node* search(struct node *temp, int val) {
int diff;
while (!is_leaf(temp)) {
diff = val - temp->key;
if (diff > 0) {
temp = temp->right;
} else if (diff < 0) {
temp = temp->left;
} else {
printf("Search Element Found!!\n");
return temp;
}
}
printf("Given Data Not Found in the tree!!\n");
return 0;
}
void inorderTree(struct node *root) {
struct node *temp = root;
if (temp != NULL) {
inorderTree(temp->left);
printf(" %d--%c ", temp->key, temp->color);
inorderTree(temp->right);
}
}
void postorderTree(struct node *root) {
struct node *temp = root;
if (temp != NULL) {
postorderTree(temp->left);
postorderTree(temp->right);
printf(" %d--%c ", temp->key, temp->color);
}
}
void traversal(struct node *root) {
if (root != NULL) {
printf("root is %d-- %c", root->key, root->color);
printf("\nInorder tree traversal\n");
inorderTree(root);
printf("\npostorder tree traversal\n");
postorderTree(root);
}
}
int main() {
printf("Hello!\n");
struct node *root = NULL;//malloc(sizeof(struct node));
LEAF = malloc(sizeof(struct node));
LEAF->color=BLACK;
LEAF->left=NULL;
LEAF->right=NULL;
LEAF->key=0;
int choice, val, var, fl = 0;
while (1) {
setbuf(stdout, 0); // Bugfix for debugging mode on Windows
printf("\nEnter your choice :1:Add 2:Delete 3:Find 4:Traverse 5: Test 6:Exit\n");
scanf("%d", &choice);
switch (choice) {
case 1:
setbuf(stdout, 0);
printf("Enter the integer you want to add : ");
scanf("%d", &val);
struct node *z = malloc(sizeof(struct node));
z->key = val;
z->left = NULL;
z->right = NULL;
z->parent = NULL;
z->color = RED;
root = insert(root, z);
printf("The root is now %d: ", root->key);
break;
case 2:
printf("Enter the integer you want to delete : ");
scanf("%d", &var);
delete_one_child(search(root, var));
break;
case 3:
printf("Enter search element \n");
scanf("%d", &val);
search(root, val);
break;
case 4:
traversal(root);
break;
case 5: // TODO
//test();
break;
case 6:
fl = 1;
break;
default:
printf("\nInvalid Choice\n");
}
if (fl == 1) { break; }
}
return 0;
}
There is verification, and there is proof. Perhaps by "complete verification" you mean formal proof of code correctness. However, in many places verification means:
functions that test properties of the data structure
applied repeatedly after several rounds of insertions and/or deletions
combined with code coverage metrics ensuring that all of your code is exercised
With map-like data structures I like to keep a simple parallel data structure, such as a hashtable of all keys in the tree. Then among the tests executed after each round of insertions and/or deletions, you can verify that all the expected keys are in the tree, as well as that the tree has correct size. Of course, this is in addition to the basic tests that the red-black invariant holds, and that the tree is sufficiently balanced, and that the tree is ordered.
It's wise to use a random key generator, with parameters for the range of key sizes, to avoid biasing your tests. Add a random selection of insert, lookup, or delete operations, with a ratio dynamically biased to grow the tree to a sufficiently large size. Run it for a few hours and see if you can get 100% code coverage; extra credit for MC/DC coverage.
A theoretical examination of the implementation is discussed in the Wikipedia article you reference.
If you want to test your particular implementation, then write the tests for each feature you want to test. Using the Wikipedia case studies would be a good start.
There are full formal proofs of red-black trees available online but it would be up to you to generate a formal proof of your particular implementation. Most people feel that formal proofs of programming programs are not worthwhile or useful.

C Binary Search Tree insertion

typedef struct word {
char *str;
int freq;
struct word *right;
struct word *left;
} Word;
Word *root = NULL; //global
while(pCounter != NULL){
if(root == NULL){
Word *x = (Word *)malloc(sizeof(Word));
x->str = (char*)malloc(strlen(pCounter->str)+1);
//printf("%s", node->str);
strcpy(x->str,pCounter->str);
x->freq = pCounter->freq;
x->left = NULL;
x->right = NULL;
root = x;
}
else {
Insert(pCounter, root);
}
pCounter = pCounter ->pNext;
}
void * Insert(Word *node, Word *root)
{
printf("inserted%s\n", node->str);
if(root==NULL)
{
Word *x = (Word *)malloc(sizeof(Word));
x->str = (char*)malloc(strlen(node->str)+1);
//printf("%s", node->str);
strcpy(x->str,node->str);
x->freq = node->freq;
x->left = NULL;
x->right = NULL;
return x;
//node = root;
}
else if (strcmp(node->str, root->str)==0){
root -> freq = root->freq+1;
}
else if (strcmp(node->str, root->str)<1){
root->left = Insert(node,root->left);
}
else {
root->right = Insert(node, root->right);
}
return node;
}
void ordered(Word *n){
//printf("ordered");
if(n != NULL){
ordered(n->left);
printf("%-30s %5d\n", n->str, n->freq);
ordered(n->right);
}
}
I'm trying to build a binary search tree to process a linked list into an ordered bst. I can get the output of root to show up correctly but not anything else. It spits out some garbage and i'm not sure why. I set up a printf statement and it shows that it is inserting actual strings. Am i doing something wrong? This isn't all the code but I think it's enough so people can understand what i'm doing. Suggestions?
return node; --> return root; As per BLUEPIXY's comment, this was the correct answer.– BLUEPIXY 2 mins ago

Visit postorder of a binary tree in order to change the content of its nodes

Given a binary tree, I should visit starting from the leaves, in order to replace the value of each node with the sum of the values ​​of its two child nodes. How should I proceed using a postorder visit?
The structure of each node is shown below.
struct node
{
int value;
struct node *left; // <- pointer to the left sub-tree
struct node *right; // <- pointer to the right sub-tree
};
Something like this?
void postorder_visit(struct node* root) {
int leftVal = 0;
int rightVal = 0;
if(root == NULL)
return;
postorder_visit(root->left);
postorder_visit(root->right);
//Don't want to change the leaves' values.
if(root->left == NULL && root->right == NULL)
return;
if(root->right != NULL)
rightVal = root->right->value;
if(root->left != NULL)
leftVal = root->left->value;
root->value = leftVal + rightVal;
}
The value at each node will be the sum of the values of its lChild and rChild.
EDIT
Edited to handle all integers (Have to do include limits.h to use INT_MAX)
int postOrder(struct node* node)
{
if(node == NULL)
{
return INT_MAX;
}
int x = postOrder(node->left);
int y = postOrder(node->right);
if(x != INT_MAX)
{
node->data = x;
}
if(y != INT_MAX)
{
node->data +=y;
}
return(node->data);
}
//Test code
void printinorder(struct node* node)
{
if(node == NULL)
{
return;
}
printinorder(node->left);
printf("%d\t",node->value);
printinorder(node->right);
}
int main()
{
struct node* root = newNode(10);
insert(root,5);
insert(root,-2);
insert(root,6);
insert(root,15);
insert(root,12);
insert(root,16);
printinorder(root);
printf("\n");
postOrder(root);
printinorder(root);
printf("\n");
}

Tutorial for Tree Data Structure in C

Could someone direct me to some tutorial on Tree Data Structures using C. I tried googling but most implementations are for C++ or Java.If someone can point me to some online tutorials that are in C it would be great.
Thanks..
Generic tree-traversal methods: http://en.wikipedia.org/wiki/Tree_traversal (see right sidebar for a huge list of algorithms to choose from).
Some tutorials:
http://randu.org/tutorials/c/ads.php
http://www.ehow.com/how_2056293_create-binary-tree-c.html
Here's a bit of tutorial code from a couple of decades ago. In fact, it's been lying around so long, I don't remember where it came from or who wrote it (could have been me, but I'm really not sure). Theoretically it's a bit non-portable, using strdup, which isn't part of the standard library, though most compilers have/supply it.
/* Warning: untested code with no error checking included. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* A tree node. Holds pointers to left and right sub-trees, and some data (a string).
*/
typedef struct node {
struct node *left;
struct node *right;
char *string;
} node;
node *root; /* pointers automatically initialized to NULL */
int insert(const char *string, node *root) {
/* Add a string to the tree. Keeps in order, ignores dupes.
*/
int num = strcmp(root->string, string);
node *temp;
for(;;) {
if ( 0 == num)
/* duplicate string - ignore it. */
return 1;
else if (-1 == num) {
/* create new node, insert as right sub-tree.
*/
if ( NULL == root -> right ) {
temp = malloc(sizeof(node));
temp -> left = NULL;
temp -> right = NULL;
temp -> string = strdup(string);
return 2;
}
else
root = root -> right;
}
else if ( NULL == root ->left ) {
/* create new node, insert as left sub-tree.
*/
temp = malloc(sizeof(node));
temp -> left = NULL;
temp -> right = NULL;
temp -> string = strdup(string);
return 2;
}
else
root = root -> left;
}
}
void print(node *root) {
/* in-order traversal -- first process left sub-tree.
*/
if ( root -> left != NULL )
print(root->left);
/* then process current node.
*/
fputs(root->string, stdout);
/* then process right sub-tree
*/
if ( root->right != NULL )
print(root->right);
}
int main() {
char line[100];
/* Let user enter some data. Enter an EOF (e.g., ctrl-D or F6) when done.
*/
while ( fgets(line, 100, stdin))
insert(line, root);
/* print out the data, in order
*/
print(root);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
struct binary_node {
struct binary_node *left;
struct binary_node *right; int value;
};
typedef struct binary_node NODE;
int search(NODE *temp, int data)
{
int found = 0;
#if 0
while (temp == NULL) {
if (temp->value == data) {
found = 1;
break;
}
else if (temp->value > data)
temp = temp->left;
else if (temp->value < data)
temp = temp->right;
}
return found;
#endif
if (temp == NULL)
return 0;
else if (temp->value == value)
return 1;
else if (temp->value > data)
return search(temp->left, data);
else if (temp->value < data)
}
NODE *del(NODE *root, int val)
{
if (root = NULL)
return ;
if (val < root->val)
root->left = delete(root->left, val);
else if (val > root->val)
root->right = delete(root->right, val);
else {
if (root->left == NULL && root->right == NULL) {
temp = root;
free(temp);
root = NULL;
}
else if (root->left == NULL) {
temp = root;
root = root->right;
free(temp);
}
else if (root->right == NULL) {
temp = root;
root = root->left;
free(temp);
}
else {
temp = min(root->right);
root->data = temp->data;
root->right = delete(root->right, temp->data);
}
}
return root;
}
NODE *insert_node(NODE *node, int val)
{
if (*node == NULL) {
node = (NODE *) malloc (sizeof(NODE));
node->left = NULL;
node->right = NULL;
node->value = val;
}
if (node->value > val)
node->left = insert_node(node->left, val);
else if (node->value < val)
node->right = insert_node(node->right, val);
else
printf("Discarding the data as it already exists in node\n");
return node;
}
}
int main()
{
NODE *root = NULL;
root = insert_node(root, 50);
insert_node(root, 4);
insert_node(root, 14);
insert_node(root, 44);
insert_node(root, 24);
insert_node(root, 34);
insert_node(root, 74);
insert_node(root, 54);
insert_node(root, 64);
print_order(&root);
search(&root, 34);
del(&root);
return 0;
}

Resources