Trees (Part 1)
Trees (Part 1)
Trees
(Part 1)
• Trees.
• Rooted tree and binary trees.
• Binary search tree.
• Traversals of the trees.
• Preorder Traversal – recursive and iterative.
• Postorder Traversal – recursive and iterative.
• Inorder Traversal – recursive and iterative.
• Operations on trees.
7.1. Introduction
J B E H
D C F G
K
Fig 1. Tree
7.2. Rooted Tree
e.g.
A In Out
A 0 2
B 1 3
C 1 1
B C D 1 0
E 1 0
F 1 0
G 1 4
D E F G H 1 0
I 1 0
J 1 0
K 1 0
L 1 0
H I K J
e.g. P
Q R
S T V
U X W
BITR get_new_node()
{
BITR temp;
temp =(BITR)malloc(sizeof(struct bin_tr ));
temp→left = temp→right = NULL;
return (temp);
}
void create_tr(BITR h)
{
BITR temp, new_node;
int chk;
char c;
do
{
new_node = get_new_node();
chk = 0;
temp = h;
scanf(“%d”, &new_node→data);
if (temp→left != NULL)
temp = temp → left;
else
temp → left = new _ node;
while (chk = = 0)
{
printf ( “ The current node is %d\n ”, temp→ chk);
printf ( “Whether the new node should be attached
to left or right?\n”);
c = getch();
if (c ==‘L’)
if (temp→left = NULL)
temp = temp→left;
else
21
6 9
4 17 24
12 10 35 31 30
13
21
6 9
4 17
12 10 35 31 30
13
21
6 9
4 17 24
12 10 35 31 30
13
Steps :
BITR que_bfs[SIZE];
struct que_b
{
BITR tval;
struct que_b *next;
}
while(! qempty())
{
temp = pop();
printf(“%d/n”, temp → data);
e.g.
while(!qempty())
{
temp = pop( ):
cnt ++;
: /* same as that of bfs */
:
}
return(cnt);
}
21
6 9
9 4
4 17 24
17 24 12 10
24 12 10 35
12 10 35 31 30
10 35 31 30 13
35 31 30 13
31 30 13
30 13
3
21 H
H 6 9
6 9 H
9 H 4
H 4 17 24
4 17 24 H
17 24 H 12 10
while (! qempty())
{
if ( temp != h)
{
printf (“%d”, temp → data);
if ( temp → left)
push ( temp → right )
if (temp → right);
push (temp → right);
}
else
{
push (temp);
printf (“\n”);
}
temp = pop ( );
}
}
while (! qempty())
{
temp = pop();
if (temp → dat == val)
return (1);
if (temp → left)
push (temp → left);
if (temp → right)
push (temp → right);
}
return ( 0 );
}
while (!qempty())
{
temp = pop();
if ((!temp→left)&&(!temp→right))
- - - -
- - - -
}
return (count);
}
Q headq, last;
void createq()
{
headq = malloc(sizeof(struct que));
headq->next = NULL;
last = headq; /* initially header itself will be the
end of the queue*/
}
int qempty()
{
return(headq->next==NULL);
}
TR poppp()
{
Q tq; /* pop function will always return the data */
TR tn;
tq = headq->next;
tn = tq->node;
headq->next = headq->next->next;
free(tq);
return(tn); /* in this case the data is
pointer to the node of tree */
}
TR getnode()
{
TR r;
r = malloc(sizeof(struct tree));
gotoxy(20,19);
printf(“Enter the value…\n”);
gotoxy(20,20);
scanf(“%d”, &r->val);
gotoxy(20,19);
printf(“ ”);
gotoxy(20,20);
printf(“ ”);
r->left = r->right = NULL;
return(r);
}
TR create()
{
do
{
i = 40;
j = 2;
k = 20;
new = getnode();
flag = 0;
if (header→left == NULL)
{
header->left = new;
do
{
gotoxy(20,19);
printf(“MOVE TO LEFT OR RIGHT (0/1)”);
gotoxy(20,20);
scanf(“%d”, &way);
gotoxy(20,19);
printf(“ ”);
if(way == 0)
{
gotoxy(40,22);
printf(“Moving to leftchild…”);
gotoxy(40,22);
printf(“ ”);
gotoxy(i-k/2,j+1);
printf(“/”);
i = i-k;
j = j+2;
k = k/2;
if(temp->left == NULL)
{
temp→left = new;
printf(“%d”, new->val);
flag = 1;
}
else
{
gotoxy(i,j);
temp = temp→left;
printf(“%d”, temp->val);
}
}
else
{
gotoxy(i+k/2,j+1);
printf (“\\”);
i=i+k;
j=j+2;
k=k/2;
if(temp->right==NULL)
{
gotoxy(i,j);
temp->right=new;
printf(“%d”, new->val);
temp->right=new;
flag=1;
}
else
{
gotoxy(i,j);
temp=temp->right;
printf(“%d”, temp->val);
}
}
}while(flag= =0);
}
gotoxy(40,19);
printf(“Anymore Y/N”);
gotoxy(40,200;
flushall();
c = getchar();
gotoxy(40,19);
printf(“ ”);
gotoxy(40,20);
printf(“ ”);
}while(c==‘y’|| c==‘Y’);
return(header);
}
TR rightmost(TR temp)
{
while(temp->right!=NULL)
temp=temp->right;
return(temp);
}
main()
{
TR t;
clrscr();
header = create();
t = header->left;
createq();
push(t);
gotoxy(10,24);
while(!qempty())
{
t=poppp();
printf(“%d\t”, t->val);
if(t->left)
push(t->left);
if(t->right)
push(t->right);
}
printf(“%d\n”, t->val);
}
6 9
4 17 24
12 10 35 31 30
13
21
4 9 35
17 31
12 30
10 13
Here we do not ask the user about the position of the node
in the tree but it will be placed as per the rule. The above
tree is constructed from the input sequence as
21 6 9 4 17 24 12 10 35 31 30 13.
Next value 6, which are, less than 21, hence it should be placed
as left child.
Now value 9, less than 21, hence as the left of 21. Left child
exists, therefore compare with left child i.e. 6, it is greater
than 6, hence will be on the right 6.
21
21
4 9
21
6
4 9
17
17
6 21
4 9
If the values are ordered say ascending then the tree will take
from of
e.g.
4 6 9 17 21
21
do
{
new_node = get_new_node ( );
printf (“Enter the value of node”);
temp = h → left;
flag = 0;
do
BITR get_new_node()
{
BITR temp;
temp = get_new_node();
scanf (“%d”, &temp→data);
}
As the name suggests, the Binary search trees have the aim
of simplifying the process of search. Here the word simplify
implies that we are required to have less number of comparisons
to check whether a particular node value is present. Now if we
are required to search for a value in the tree, we can simply
modify the insert function as shown below
e.g.
21,6,4,9,17,12,10,13,24,35,31,30.
do
{
printf(“%d”, t→data);
if (t→right)
t = t →right;
t = t →left;
if (t == NULL)
}while(!stack_empty());
}
1. Preorder Traversal
2. Postorder Traversal
3. Inorder Traversal
We are very much a aware of the fact that there will be left
child and right child for any node in the binary tree. The
sequence in which the node, its left child and right child are
printed, determines the traversal.
B D
C E G
Processing order : A B C D E F G
void pre_order ( TR t )
{
if (t)
{
printf(“%d”, t→data);/* visit the node */
pre_order (t→left); /* visit the left subtree in
preorder */
pre_order (t→right); /* visit the right subtree in
preorder */
}
}
You may implement the above function and test it with various
trees.
B D
C E G
Processing order: C B F E G D A
void post_order ( TR t )
{
if (t)
{
post_order (t→left); /* visit the left subtree in
postorder */
post_order (t→right); /* visit the right subtree in
postorder */
The steps are shown using figures below. Consider the tree.
70
60 99
50 81
From the root all the nodes will be pushed in the stack,
as we travel to the root of each node, till we get NULL.
70 70 1 Step 2
60 1 Step 3
70 60 60 1 Step 2
50 1 Step 3
70 60 50 50 1 Step 2
44 1 Step 3
70 60 50 44 44 1 Step 2
NULL Step 3
70 60 50 44 1 Step 5
44 2 Step 6.b
70 60 50 44 44 2 Step 6.c
NULL Step 6.d
70 60 50 44 2 Step 5
44 2 Step 6.a 44
Now pop the next node from the stack and repeat the whole
process
70 60 50 1 Step 5
50 2 Step 6.b
flag of 50, has changed to 2 and pushed in the stack
70 60 50 50 2 Step 6.c
The next node will be 50’s right child i.e. 54, processing
repeats from here
54 1 Step 6.d
70 60 50 54 54 1 Step 2
52 1 Step 3
70 60 50 54 52 52 1 Step 2
NULL Step 3
70 60 50 54 52 1 Step 5
52 2 Step 6.b
70 60 50 54 52 52 2 Step 6.c
52 2 Step 6.a 52
70 60 50 54 2 Step 5
B D
C E G
void in_order ( TR t )
{
if (t)
{
in_order (t→left); /* visit the left subtree in
inorder */
printf(“%d”, t→data);/* visit the node */
}
}
e.g.
In previous tree
temp=malloc(sizeof(struct tree));
temp-> left = temp-> right =NULL;
scanf("%d", &val);
temp->data=val;
return(temp);
}
if(temp->right)
{
printf("\t\t")
display(temp->right);
}
}
else
{
if (root->right) /* whether it exists in right
subtree*/
root=root->right;
else
return (NULL);
}
}while (1);
}
void parent(void)
{
TR result;
int val:
void brother(void)
{
int val, result;
char ans ='Y'
while (ans=='Y')
{
clrscr();
printf("\n\n\n");
printf("Enter node to find brother :");
scanf("%d", &val);
result = brother_find(val);
if(result==-1)
0{
printf("node is not in the tree!\n");
printf(“Enter node properly!\n\n");
}
else
if(result ==-999)
{
printf ("\n\n Node is the root. \n It has no
brother!");
getch();
}
else
{
if (result ==0)
printf ("\n Node has no brother !\n");
else
printf("\n Brother is %d !", result);
getch();
}
TR rightmost(TR node)
{
while (node->right!=NULL)
node=node->right;
return(node);
}
while(p->left !=temp)
{
temp=p;
p=parent_find(temp->data);
}
return (p->data);
}
}
}
while(ans=='Y')
if(pred==-1))
{
printf("\n Node itself is not present. \n");
printf("Enter node properly !\n\n\n");
getch();
}
else
if (pred==-999)
{
printf("\n this node has no predeccessor! N");
getch();
}
else
{
printf("Predeccessor is %d" pred);
getch();
}
printf("\n\n Continue (y/n)”);
ans=tpupper(getch());
}
}
main()
{
create_tree();
brother( );
parent ( );
successor ( );
preedeccessor();
}
Algorithm:
Pseudo code
1./* Initialize */
if HEAD->lptr != HEAD /* no tree exists */
CUR = HEAD->lptr;
PARENT = HEAD
D = ‘L’
else
printf(“NODE NOT FOUND “);
return;
46 58 69
47
Before Deletion
55
30 61
46 58 69
After Deletion
CUR 55
40 61 Node to be deleted = 40
55
30 61
58 69
After Deletion
55 CUR
40 61 Node to be deleted = 61
21 46 58 67
57 60 70
56
Before Deletion
55
40 67
21 46 58 70
57 60
56
40
20 100 CUR
180 300
280 310
290
Before Deletion
40
20 100
90 280
180 300
290 310
After Deletion
+ *
2 / - -
* + 4 1 2 /
3 + 2 3 10 2
- 7
4 /
6 2
e.g.
- -
4 - - 3
2 3 4 2
a - b( c * d / a + a) * b + a
a – b - ( c * d / a + a ) * b + a
= a – b - ( c * e 1+ a ) * b + a
= a – b - ( e2 + a ) * b + a
= a – b – e3 * b + a
= a – b - e4 + a
= e6 + a
= e7
Forming the tree will be easy from any of the above
notations. Travel from bottom to root.
+ ⇒ + ⇒ +
e7=
a b - a - a
e5 e4 - e4
a b
⇒
+
- a
- *
⇒ +
- a
- *
a b + b
e2 a
⇒ +
- a
- *
a b + b
* a
c e1
⇒ +
- a
- *
a b + b
* a
c /
d a
a – b - ( c * d / a + a ) * b + a
= a – b - ( c * ( d / a + a ) * b + a
= a – b - ( ( c * ( d / a + a ) ) * b + a
= a –b - ( ( ( c * ( d / a ) ) + a ) * b + a
= ( a – b ) - ( ( ( c * ( d / a ) ) + a ) * b ) + a
= ( ( a – b ) - ( ( ( c * ( d / a ) ) + a) * b ) ) + a
= ( ( ( a – b ) - ( ( ( c * ( d / a ) ) + a ) * b ) ) + a )
( ( ( a – b ) - ( ( ( c * ( d / a ) ) + a ) * b ) ) + a
e5 e1
e2
e3
e4
e6
e7
Exercises: