Anda di halaman 1dari 36

DS - DSAA ( Common Topics )

4. Binary Trees
A tree consists of a finite set of elements, called nodes, and finite set of directed
lines called branches, that connect the nodes. The number of branches associated
with a node is called Degree of a node. If a tree is not empty then the first node
is called a root.
Binary tree is a tree with all the nodes having degree not more than two. It
consists of a root node with one or two branches. These branches are also called
left or right subtrees. Each branch can consist of further one, two or no branches
(i.e. subtrees). A tree having no nodes is called null tree. A binary tree is shown
diagrammatically as follows.
Root node
A
A
Internal Nodes
B
B

C
C
Leaf Nodes

D
D

E
E

F
F

Fig. 1

In the above figure a tree with 6 nodes is shown. Node with value A is at the root
of the tree or we can say A is a root node. Nodes B and C appear immediately in
the left and right subtrees of node A. Here B is called Left child and C is called
Right child of node A. Similarly D and E are the left and right children of B. Also,
A is called father of B and C. A node that has no children is called a Leaf or a
Leaf node. In above figure F,D and E are the leaf nodes.
If every non-leaf node in a binary tree has non-empty left and right subtrees, the
tree is termed as Strictly Binary Tree.
The root of a binary tree is said to be at level 0. Level of its children is 1. Thus,
level of any node in a tree is one more than level of its father. Nodes B and C are at
level 1. Nodes D,E and F are at level 2.
Depth or Height of a binary tree is the maximum level of any leaf node in the
tree.
Complete Binary Tree is a strictly binary tree of depth d whose all leaves are at
level d.

Binary Tree structure ( Binary Tree Representations ) :


From above discussion it is clear that a tree consists of multiple nodes. Each node
must contain the data to be stored and tow links, one to the left child (subtree)
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

1 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


and other to the right child (subtree). Some implementations also use a link for a
father node.

1. Linked (i.e. Node) implementation of a Binary Tree :


Node of a Binary tree holds three major parts (fields).
Data field : Holds data for the element.
Link Fields : There are two link fields i.e. pointers for the two sub-trees (Left and
Right subtrees) of the current Node. If a particular subtree (say Left subtree ) does
not exist for a node then that pointer will hold NULL link.
A node for a Binary tree can be implemented by a following structure definition,
struct Node
{
int data;
struct Node *left, *right;
};
The above node consists of an int no as data field and two pointer variables
left and right that are used to store the references for the left and right
subtrees.
Following figure shows Binary tree with Six nodes.
Node with value 10 is Root of the Tree.
12, 5, 20 are leaf nodes.
Depth (Height) of the tree is 3.

1
0
1
5
1
2

2
0

Fig. 3

10

15

Notes prepared by, Santosh Kabir.


Mobile : 98336 29398

2 of 36

NULL

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


2. Array implementation of Binary Trees:
Nodes in the tree are numbered in a particular sequence.
The root element is stored at index 0. In the next level the numbering will start
from the left-most node and the nodes will be numbered in that order.
An almost complete binary tree as shown in figure below can be represented using
an array.
0
A

Fig. 4

Thus if the tree has 6 nodes then root will be numbered 0 and the node that is at
the right-most position in the last level will be numbered as 5.
In array implementation, the information will be stored in the array elements in a
continuous manner and the numbers discussed above will be the indexes of the
different nodes in array. The above tree can be represented in array as follows,
0

Fig. 5

Positions of Child Nodes : The node at position p has two sons (i.e. children)
at positions 2p+1 and 2p+2. The relationship is shown with the arrows in above
figure.
In case of other trees (trees that are not complete or almost complete) as shown in
the figure (a) below, its almost complete tree is imagined as shown in fig.(b) below.
The tree in array will be as shown in figure (c) with some empty array elements.
0

A
1
C

2
B

Fig. a
0

Notes prepared by, Santosh Kabir.


Mobile : 98336 29398

3 of 36

Fig. b
Fig. 6

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


A
B
C
null null D
Fig. c
If in a particular level child-nodes are present on right but left part is empty then
those absent child nodes are also numbered.
Thus the array implementation has to indicate the null nodes by some means.
This is one of the drawbacks of Array implementation of linked list.
Tree is a collections of elements in which one element is linked to further two or
more elements. Linked list is a linear structure, where as tree is non-linear
structure.

Common operations on binary trees:


( Linked implementation of Binary Tree )
Node structure (as given above ).
For following operations and corresponding C functions we will assume a global
variable (pointer) for Root of the tree as follows,
struct Node * root;

Binary Tree Traversals:


Tree traversal means moving through all the nodes or visiting all the nodes in a
tree.
Binary tree traversals require that each node of a tree be processed once and only
once in a predefined sequence.
While traversing the tree one can process the data in the node according to the
requirement of a program. For example one can traverse a tree to display all the
positive numbers stored a tree or to get a sum of all the even numbers in a tree.
All the traversal methods read the root node reference and then using links in the
nodes move through the entire Tree.
According to the order in which nodes are processed, there are following types of
Tree Traversals :
1. Breadth First Traversal ( BFT ) :
2. Depth First Traversal ( DFT ) :
a. In-order Traversal,
b. Pre-order Traversal,
c. Post=order
Traversal
Consider following tree with the following values: A, B, C, D, E, F, G.
A

C
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

D
4 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )

Fig 7

Breadth-First Traversal (BFT):

In this traversal, root is processed first then each level of Tree is processed from
the second level to the height of the tree.
Each level is completely processed before the next level is started. Each level is
traversed from left to right.
For this purpose we use a Queue (since its a FIFO list) to store child node
references.
The algorithm for this type of traversal is as shown below,
A-1
Algo: BFTraverse
1. Read a root Node reference
2. Create an empty Queue
3. Store the root reference in a Queue
4. While Queue has nodes, repeat following
a. Remove first element (node reference) from queue
b. Process the node (i.e. node referred by the element)
c. If left child of the node exists
Add left child link in a queue
d. If right child of the node exists
Add right child link in a queue
3. Go to step 4

The algorithm assumes that the Queue holds links (i.e. pointers) for tree nodes.
Traversal Path : A B F C D G - E

Function :
// Traversing a Tree (Breadth First Traversal )

void BreadthFirstTrav( )
{
if( root != NULL )
{
struct Node *r =root;
Add( r );
while( ! IsQEmpty() )
{
r = Remove();
printf("%d\t", r->data );
if( r->left != NULL )
Add( r->left );
if( r->right != NULL )
Add( r->right );
}
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

5 of 36

Note : Add( struct Node * ) is a function of


Queue, to add new node pointer to Queue.
Refer to full program discussed in class.

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


}
else
printf("Tree is empty\n");
}

Depth First Traversals (DFT):


Figures below show the traversal sequences for these three types. Node is shown
with letter N in circle, Left subtree with letter L and Right subtree with letter R.
N

Pre-order (NLR)
(LRN)
8-a

In-order (LNR)
8-b

L
Post-order
8-c

Pre-order Traversal:
In the preorder traversal current node is processed first, then its left and right
subtrees are traversed. This is done for every node in the path. The process is
repeated till the entire tree is traversed. This, can be achieved with a following
recursive algorithm. The input to the algorithm is root node reference.
A-2
Algo: Preorder( Node reference )
1. If Node reference is not null
a. Process the current node
b. Taverse left-subtree of the current node
c. Traverse right-subtree of the current node

The Pre-order traversal path : A B C- E- D F - G

Function :
void Preorder( struct Node *r )
{
if( r != NULL )
{
printf( "%d\n", r->data );
Preorder( r->left );
Preorder( r->right );
}
}
In-order Traversal:
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

6 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


Inorder traversal traverses the left subtree first then processes the current node
and then traverses the right subtree. The recursive algorithm for the inorder
traversal is as follows,
A-3
Algo: InTraverse( Node reference )
1. If Node reference is not null
a. Traverse left-subtree of the current node
b. Process the current node
c.

Traverse right-subtree of the current node

In-order Traversal path : E C B D A F - G


Function :
void Inorder( struct Node *r )
{
if( r != NULL )
{
Inorder( r->left );
printf( "%d\n", r->data );
Inorder( r->right );
}
}
Post-order Traversal:
In post-order traversal the root (current node ) is processed after the subtrees are
processed.
The recursive algorithm for post-order traversal is as follows,
A-4
Algo: PostTraverse( Node reference)
1. If the node reference is not null
a. Traverse the left-subtree of a current node
b. Traverse yhe right-subtree of a current node
c. Process the current node

Post-order traversal path : E C D B F G - A


Function :
void Postorder( struct Node *r )
{
if( r != NULL )
{
Postorder( r->left );
Postorder( r->right );
printf( "%d\n", r->data );
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

7 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


}
}

Inorder Traversal using Stack:


The recursion internally uses stack (in computer system memory). The recursive
functions can be replaced by iteration, in some cases, by using a (user defined)
stack. The method inTraverse()given below can be added to the BinaryTree
class.
The algorithm uses a stack of Node reference variables,
A-5
Algo. InTraverse( Root Node )
1. Create an empty stack to hold Node pointers.
2. read the root pointer into a variable
3. Repeat following steps
a. While null reference not found
i. Push the pointer to the stack
ii. Read the left child link of the node.
b. If stack is not empty do following
i. Pop a pointer from stack
ii. Display the node given by pointer
iii. Read the right child link from this node
4. go to step 3 if stack has elements or current pointer is not null

The algorithm assumes a Stack of tree node pointers.

Function :
void InTraverse( )
{
struct Node *r = root;
do
{
while( r != NULL)
{
Push( r );
r = r->left;
}
if( ! IsStackEmpty() )
{
r = Pop();
printf("%d\t" , r->data );
r = r->right;
}
}while( !IsStackEmpty() || r!= NULL );
}
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

8 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )

Threaded Binary trees:


In the previous topics we discussed the most important operation of binary tree
i.e. tree traversals using depth-first technique. It uses a recursive function to
traverse a given tree. The recursion involves multiple function calls and its an
inefficient process. The more efficient alternative is use of stack. The reason we
use recursion or a stack is that, at each step, we cant access the next node in a
sequence directly (i.e. we have to move backwards and retrieve a reference from a
stack to the node which we want to access next). This is called backtracking. For
example in inorder tree traversal we follow the left child links to get the leftmost
leaf-node. When we get a leftmost leaf-node, we begin backtracking to process the
right subtree that we bypassed on our way down. This especially inefficient when
the parent node has no right subtree.
A

Fig. 9

Consider inorder traversal for the tree shown above. We visit the left most leaf B
and after processing it move to C and for this we use recursion or stack. Note that
when we are processing B we do not need recursion or stack because Bs right
subtree is empty. Similarly after processing node D using recursion or stack we
must return to C before moving to A. Here again we need not visit C.
From this example, it is clear that the nodes whose right subtree is empty create
more work when we use stack or recursion.
The solution to this is Threaded tree. In a threaded tree, the null pointers are
replaced by pointers to it successor node. In inorder traversals whenever right
subtree pointer is empty, we can use a pointer to point to the successor of the
node. In other words we can use right null pointer as a thread.
The figure below shows threaded binary tree with nodes.
A

C
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

9 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )

Fig 10

Binary Search Trees (BST):


Binary Search Tree is a binary tree in which left subtree of every node is either
empty or contains key values less than the node and the right subtree is either
empty or contains key values greater than or equal to the node.
Node

Left subtree

<N

Fig. 11

Right subtree

>=
N

1
1
5
5

Example BST :

2
2
5
5

8
8
4
4

1
1
8
8

1
1
0
0

Fig. 12

1
1
2
2

Building a Binary Search Tree:


Suppose, we entered five numbers as: 10, 16, 6, 4, 8 to build a Binary Search
tree. The steps to create the tree will be as follows.

10

10

10

1
1

1
16

16

16

10

13-a

13-b

13-d

10

1
6

13-c

16
2

Notes prepared by, Santosh Kabir.


4
Mobile : 98336
29398

10 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


Fig. 7

13-e

To add a new node in the tree we have to find where the new node will be linked.
The search starts from root of the tree.
Then according to value of new node we move towards left or right in a tree till
empty subtree is found.
The new node is linked to last node found.
e.g to add node with value 8 to the tree in Fig.-13.d, we start checking from the
root node i.e. value 10. Since the value to add is smaller than value in current
node, we move to its left child. Left subtree of 10 is not empty. Here the value to
add is larger than that in the current node. Hence we move to right child. Since
the right subtree is empty (i.e. link is null), the new node with value 8 is linked to
this node as a right child.
In Binary Search tree a new node is always added (or inserted) as a Leaf node.

Binary Search Tree operations:


The node composition for this tree is same as that for general binary tree.
All the operations (and algorithms) that we discussed so far for general binary tree are also applicable to the
Binary Search Tree.
Binary Search tree has following additional operations.

Searching a Node :
Note : (Imp )
In case of linear structures like arrays or linked lists multiple elements are stored one after the other. To search
for a particular element we need to begin from the first element and go through the list linearly (sequentially).
Consider we have a list of N (N=10) elements stored in any linear structure.
50, 35, 20, 75, 65, 80, 90, 60, 30, 45
To get any element from the list we need maximum N attempts to reach the element. If its a last element then
search goes through N elements. In average case the search will take N/2 attempts. If above elements were
stored in linear list, then to get the last element (here, 45) will take 10 attempts on average 5 attempts.
Now consider the elements are stored in Binary Search Tree form as shown below.

5
0

7
5

3
5
2
0
3
0.
Notes prepared by, Santosh Kabir
Mobile : 98336 29398

4
5

6
5
3
5

11 of 36

8
0
9
0

Fig. 14

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )

Now, to search any element in a binary search tree, we begin from root of the tree and advance to left or right
child if the current node is not the required node.
For example to search the node with value 30, we will follow the path 1 shown in above figure. This will take 4
attempts to reach the node 30. Also to reach node 45 we follow the path 2 that will take 3 attempts and for
reaching node 90, we follow path 3 that will take 4 attempts.

Thus, it is clear that to reach any node starting from first node, the
maximum attempts required will be equal to the depth (i.e. height) of the
binary search tree, which is very fast compared to sequential searching.
Hence, this type tree is called as Search Tree.
The algorithm and function to search the node is given below. The search
algorithm returns the pointer for the node if found else returns null pointer to
indicate search failed.
Algo: Search Node( key value to search )
Returns: Reference for the required node
1.Read pointer for root node
2. While pointer is not null repeat following
a. If current node holds the required key then
stop search
b. Else
If the key is less than the key in current node,
Read its left child pointer
Else
Read its right child pointer.
3. Return the pointer

Function :
struct Node* SearchNode( int v )
{
struct Node *r = root;
while( r != NULL )
{
if( r->data == v )
break;
else
{
if( v < r->data )
r = r->left;
else
r = r->right;
}
}
return r;
}

Inserting new node in BST:


Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

12 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


New node is always inserted (i.e. added) in a binary search tree as a leaf node.
Refer the example given in topic Building Binary search tree and figure 13.

Algo: Insert Node( value to add )


1. Create a new node with given value and put null in both left and right pointers.
2. If the tree is empty then,
a. make it a root node
3. Else
a. Read the root node pointer
b. While pointer is not null, do following
i. Keep the current link aside as a parent node link
ii. If value is less than that in current node, then
1. Read pointer to left child
iii. Else
1. Read pointer to right child
c. If value is less than the parent node value, then
i. make new node a Left child of parent
d. Else
i. make new node a Right child of parent

Non-recursive function :
void InsertNode(int v)
{
struct Node* nw, *cur=NULL, *par=NULL;
// allocate and create new Node

nw = (struct Node*)malloc(sizeof(struct Node));


nw->data = v;
nw->left = nw->right = NULL;
if( root == NULL) // if tree is empty
{
root = nw;
}
else
// find the node, where to link new node
{
cur = root;
while( cur != NULL )
{
par = cur;
if( v < cur->data )
cur = cur->left;
else
cur = cur->right;
}
if( v < par->data )
par->left = nw;
else
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

13 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


par->right = nw;
}
}

Recursive function :
struct Node* RecInsert( struct Node* t, int v )
{
if( t == NULL )
{
t = (struct Node*) malloc( sizeof(struct Node) );
t->data = v;
t->left = t->right = NULL;
}
else if( v < t->data )
t->left = RecInsert( t->left, v );
else
t->right = RecInsert( t->right, v );
return t;
}

Deleting a node:
To delete a node from a BST we have to first locate it. There are four possible cases
in deleting procedure.
Consider a following BST.
40

25
12

50
34

30

60

Fig. 15

38

a. Deleting a Leaf node : (A node to deleted has no child ): Here the


corresponding child node link in the parent node is set to null.

40

40

25
1
2
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

25

null

14 of 36

Fig. 16.a

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )

Right link of node 25 is set to null

Deleting node 12.

b. A node to be deleted has one sub-tree (Node has one child): There are two
cases, the child node (of the node of the node to be deleted) may be present
on the left or right side. If there is only a Left (Right) child, then we can
simply update the corresponding child pointer in the parent of the node to
be deleted.
40

40

5
0

60

Fig. 16.b

60

Right link of node 40 is linked to node 60


Deleting node 50.
c. The node to be deleted has two children: In this case the in-order
successor of the node (to be deleted) is found. The data in this node is kept
in the node to be deleted. Then this in-order successor of the given node
(node to be deleted) is actually deleted.
Deleting node 25.
40

2
5
12

30

30
34

30

40

40

12
38

12

34
30

34
38

38

Value in Inorder successor i.e. 30 copied into the node (i.e. 25) to
be deleted. And then the node 30 is deleted using steps shown in
case a or b above.

Fig. 16.c

Non-Recursive Function :
void DeleteNode(int v)
{
// root is a tree root pointer
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

15 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


struct Node * curr, *sucr=NULL, *par=NULL;
curr= root;
if (curr == NULL) // Tree root is null
{
printf("Tree is empty\n");
return;
}
while( curr != NULL && curr->data != v )
{
// par keeps link for parent node of the node being checked

par = curr;
// Select a child (left or right) to search further

curr = v < curr->data ? curr->left : curr->right;


}
if( curr == NULL) // if node not found stop procedure
{
printf("\n\tNode not found in a tree\n");
return;
}
// If a node has 2 child nodes

if(curr->left != NULL && curr->right != NULL)


{
// Select in-order successor of the node to deleted

par = curr;
sucr = curr->right;
while( sucr->left != NULL)
{
par = sucr;
sucr = sucr->left;
}
// update data in node to deleted

curr->data = sucr->data;
// Let the successor be a cur. node. i.e. a node to be deleted

curr = sucr;
}
// If the node has no child (i.e the Node is a Leaf-node)

if(curr->right == NULL && curr->right == NULL)


{
if( curr == root ) //for a tree with single node
root= NULL;
else
{
if(par->left == curr)
par->left = NULL;
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

16 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


else
par->right = NULL;
}
return;

// Stop procedure

// if the node has only right child

if( curr->right != NULL && curr->left == NULL)


{
if( curr == root )
root = root->right;
else
{
if( par->left == curr )
par->left = curr->right;
else
par->right = curr->right;
}
return;
// Stop procedure
}
// if the node has only left child

if( curr->right == NULL && curr->left != NULL)


{
if( curr == root )
root = root->left;
else
{
if( par->left == curr )
par->left = curr->left;
else
par->right = curr->left;
}
return;
// Stop procedure
}
}

Recursive Function :
struct Node* RecDelete( struct Node *r, int v)
{
struct Node *temp;
if( r == NULL )
printf("Given node not found\n");
else
{
if( v < r-> data)
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

17 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


r->left = RecDelete( r->left, v );
else if ( v > r->data )
r->right = RecDelete( r->right, v );
else
{

// node with two children

if( r->left != NULL && r->right != NULL )


{
temp = r->right;
while( temp->left != NULL )
{
temp = temp->left;
}
r->data = temp->data;
r->right = RecDelete( r->right, r->data );
}
else
{
temp = r;
if( r->left == NULL )
r = r->right;
else if( r->right == NULL )
r = r->left;
free( temp );
}
}
return

r;

}
}

Binary Tree applications:


1. Expression Trees:
We will consider expressions with only binary operators in the form:
operand1 operator operand2
An expression tree is a binary tree with following properties:
1. Each leaf is operand.
2. The root and internal nodes are operators.
3. Sub-trees represent sub-expressions and the root (of the subtrees) holds
the operator.
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

18 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


4. Given an expression tree, the three standard traversals (inorder, postorder
and preorder) represent the three different expression formats: infix, postfix
and prefix.

Building and Expression tree for a given expression :


Expression tree for an expression A * ( B + C ) - D is built using following steps:
1. Number the operators with their operating order in the expression. ( e.g. in
above expression order will be : + , * , 2. Choose the operator that will operate at the end. Here, (- D) is last
evaluated. Make root node to hold operator -, put right operand ( D ) on the
right , and the left operand i.e. A*(B+C) into right child.
3. Now the child nodes of node with - are holding the two expressions
[ A*(B+C) ] and [ D ]. Use same steps as given in step 1, to split the
expressions into further two parts. The right subtree cant be split since it
holds only D. Split left tree at the operator *, since, in the expression
A*(B+C), it will operate last.
4. Repeat these steps till all child nodes have single operands.
The steps in building the expression tree for the above expression are shown with
the following figure.

A*(B+C
)

(B+C
)

Fig. 17

D
A

+
B

Infix traversal:
This produces the infix expression. When we generate an infix expression, we
must add opening parenthesis at the beginning of each expression and a closing
parenthesis at the end of each expression. This is required since, the root of the
tree and each of its subtrees represents a sub-expression. The algorithm for infix
traversal of an expression tree is as follows,
Input: Root of the expression tree.
Output: Infix expression.
1. If link is not null
a. If node has operand
Print operand
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

19 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


b. Else
Print open parenthesis
Traverse left subtree
Print data in the node
Traverse right subtree
Print close parenthesis
End of If
2. Stop.

Evaluation of an expression:
The algorithm to evaluate an expression stored in a binary tree is as follows,
Input: Tree node
Output: Returns value of the expression
If symbol in a node is an operand
Return the float value of symbol
Else
Evaluate left subtree
Evaluate right subtree
Read the operator in the node
Operate the operator on the two operands to get value of expression
Return the value.

Note : The algorithm assumes tree nodes hold symbols or digits i.e. characters.
The method works on the basis of post-order traversal of a binary tree. It
recursively evaluates the left and right subtrees and then applies the operator
(stored in the root of the two expressions).

Functions for different operations on Expression Tree :


int IsOperand(char c) // function to check for whether a symbol is an Operand
{
if( c>='0' && c<='9' )
// If its an operand (i.e. digits )
return 1;
else
return 0;
}
void CreateTree( char post[] ) // function to build tree for given postfix expr.
{
struct Node *nw, *le, *re;
int i;
char c;
stak.top = -1; // initialize stack
i = 0;
while( post[i] != '\0' )
{
c = post[ i ];
// read ith char.
// Create new node for the char.
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

20 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


nw = (struct Node*)malloc( sizeof(struct Node) );
nw->symb = c;
nw->left = nw->right = NULL;
if( IsOperand(c))
Push( nw );
else
// if operator: build a tree using two subtrees from two operands on
stack

{
re = Pop( );
le = Pop( );
nw->left = le;
nw->right = re;
Push( nw );
}
i++;

// advance to next symbol in the given expr.

}
root= Pop( );

// get the root i.e. tree

}
float Operate(char ch,
{
switch( ch )
{
case '+' : return
case '-' : return
case '*' : return
case '/' : return
}
}

float op1, float op2)

op1
op1
op1
op1

+
*
/

op2
op2
op2
op2

;
;
;
;

float EvalTree( struct Node *t ) //Evaluates the expr. in the tree


{
float opnd1, opnd2, v;
char ch;
ch = t->symb;
if( t->left== NULL && t->right==NULL)
return ( ch -'0' );
else
{
opnd1 = EvalTree( t->left );
opnd2 = EvalTree( t->right);
v = Operate( ch, opnd1 , opnd2 );
}
return v;
}
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

21 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


void Inorder( struct Node *r)
{
if( r != NULL )
{
if( r->left != NULL && r->right != NULL )
printf(" ( " );
Inorder( r->left );
printf("%c ", r->symb );
Inorder( r->right );
if( r->left != NULL && r->right != NULL )
printf(" ) " );
}
}
void Preorder( struct Node *r)
{
if( r != NULL )
{
printf("%c ", r->symb );
Preorder( r->left );
Preorder( r->right );
}
}
Note : Above functions also use a Stack of Nodes.

Huffman Code (Huffman Algorithm) :


The ASCII characters are 8-bit long (and Unicode characters are 16 bit long) i.e. each character corresponds to
one byte (or two bytes in case of Unicode char) of memory i.e. the character length does not vary. Thus, a data
or file having 50 characters will take 50 bytes of memory or storage space on disk.
Huffman code gives a method for storing the same amount of data in smaller space. In Huffman code we
assign shorter codes to the characters that occur more frequently and longer codes to those that occur less
frequently. For example characters E and T occur more frequently in any text in English language. These
characters can be assigned only one bit. (e.g. 0 for E and 1 for T). The group characters that occur less than E
and T (e.g. A,O, R and N) can be assigned 2 bits and so on. Thus, using the Huffmans code the data storage
space can be reduced.

What is Huffman Code and its use :


Huffman Coding algorithm is used for Data Compression.
For creating codes, it uses Binary tree of characters: called as Huffmans Tree.
Large data (like data in file) can be compressed by using Huffmans codes for the
characters in the data.
The Compressed data will serve following purposes:
Occupy less amount of space on storage devices ( disk, pen drives etc.).
Since data is in compressed it can much quickly transferred over networks.
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

22 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


Since, data is coded, it safe to handle or send the data over internet.
Same codes can be used to de-compress the data and get original data back.
To assign codes to the characters following steps are taken:
1. Assign weights to each character using the frequency of their occurrences.
2. Arrange them in the ascending order of their frequencies.
3. Build a tree (called Huffman Tree) using the characters where the characters
will always appear at the leaf of the tree.

Properties of Huffmans tree :


Each nodes in the tree hold a character and its frequency.
The leaf nodes hold the characters for which coding is to be done.
Each internal node holds the sum of the frequencies of it subtrees.
The branches are assigned value 1 or 0 : Left branch:0, Right branch: 1
The code for each character is generated by tracing the branches from Root to the
character(leaf node). While tracing the path, branch codes (i.e. 1 / 0) are collected.
This sequence of 1s and 0s forms a code for the character.

Huffman Algorithm (for building the Tree ) :


The actual Algorithm for building an Huffman Code Tree is as follows.
Here, a Huffman tree is built which is a binary tree. Each tree node holds
character and frequency of occurrence as data field. We assume a min-priority
queue to hold tree nodes in ascending order of character frequency.
Algo:
Input : a string to form tree from
Output : Code tree for the string
4. Compute frequencies of occurrences of each character in the given string
5. Initialize an empty min Priority Queue to hold tree nodes (according to frequencies of
chars.)

6. For each (distinct) character in the given string do,


a. Create a node to hold character and its frequency
b. Insert the node into the Queue
7. While queue has at least one element
a. Remove node t1 from a queue. Store the frequency into f1
b. Remove (next) node t2 from a queue. Store the frequency into f2. (here f1<=f2)
c. Create a new binary tree T with t1 as left subtree and t2 as right subtree, and a root
node with frequency f1+f2.
d. Insert T (with frequency f1+f2) into the Priority Queue .
8. Remove last element (tree node)
9. return the tree node i.e. tree.

Tree building and Coding Example :


Consider the four alphabets and their frequencies as follows,
A-15, B- 5, C- 9 and D- 3

Notes prepared by, Santosh Kabir.


Mobile : 98336 29398

23 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


Step 1 : Create a Min-priority queue by inserting nodes according to the
frequencies (lowest frequency character node first)
Step 2: Initial Min Priority Queue will be as follows.
D

3
5
9
15
Step 3 : Remove D and B and build a tree with D as left child, and a Root Node DB
with frequency 8. Insert the node root node (DB) into a min-priority queue.
Tree
DB

Queue

DB

15

Step 3 : Now remove two nodes ( here DB and C ). Combine DB and C to form a
root node (DBC) with frequency (8+9 = 17).
Tree
DBC

17
Queue

DB

C
A

15

DBC
17

Step 4: Combine A and DBC to get Huffman tree for the given characters.
ADB
ADB
C
C

A
0

15

32
1

A
A

D
D
B
B

17

DBC
DBC

1
C
C

D
D

B
B

3
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

5
24 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


Branches are numbered 1 or 0 as shown in the above figure (bold digits).
Code for A is generated by tracing path a from Root to A : 0
Code for D is generated by tracing path b from Root to D : 1 0 0
Codes for the characters :

A
B
C
D

0
101
11
100

Thus the message (data) containing information


ABAACACBCDA (11 bytes i.e. 88 bits)
will be encoded as 0 1 0 1 0 0 1 1 0 1 1 1 0 1 1 1 1 0 0 0(20 bits).
If the Huffman encoded data is, 1 0 1 0 1 1 0 1 0 0 0 1 0 1 1 1.
Then the actual data is, BACADABC.

Following code shows main part of a program for Building Huffman code
Tree :
struct Node // Node to hold char and its freq. in text
{
char chr;
int freq;
struct Node *left, *right;
};
// some variables used in following functions

struct Node *root;


int freqs[128];
// to hold frequencies of all the chars.
void GetCharFreq( char s[] ) // counts frequency of each char. in the given text
{
int i;
for( i=0; i<128; i++ ) // initialize all freq to 0
freqs[i] = 0;
// following lines count frequencies of chars.

i = 0;
while( s[i] != '\0')
{
char ch = s[i];
freqs[ (int)ch ] ++;
i++;
}
}
// Function to build a Huffman Code tree for the given character string

void BuildCodeTree( char str[ ] )


Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

25 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


{
int i, f1, f2;
struct Node *nw, *t1, *t2;
// Get frequencies of occurrences of the characters in the given string

GetCharFreq( str );
// Create an empty Priority Queue

q.fe = q.re = -1;


// For each character with non-zero freq. make a Node to hold freq. and
// add it into a Priority queue.

for(i=0; i< 128; i++)


{
if( freqs[i] != 0 )
{
nw = (struct Node*) malloc( sizeof( struct Node) );
nw->chr = (char) i ;
nw->freq = freqs[i];
nw->left = nw->right = NULL;
Add( nw );
}
}
// While Q has only at least one node left

while( 1 )
{
t1 = Remove();
if( IsEmpty() )
{
root = t1;
break;
}
f1 = t1->freq;
t2 = Remove();
f2 = t2->freq;

// Remove node with min freq.

// Remove node with 2nd min freq.

// build a tree nw with t1 as left subtree and t2 as right subtree


// and root with freq. = f1 + f2

nw = (struct Node*) malloc( sizeof( struct Node) );


nw->chr = '\0'; // parent node holds null char
nw->freq = f1+f2;
nw->left = t1;
nw->right = t2;
Add( nw );
}
}
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

26 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )

AVL-Trees :
Binary Search trees are used for searching data using the key values stored in its nodes. In some
cases binary search trees may not give satisfactory searching times, because of imbalance in its
subtrees.
In case of Binary Search Tree, if multiple nodes are created by reading keys one by one, it can
happen that the height of the one of the sub-trees (say right sub-tree) will go on increasing and the
other (say left) may not increase at all or may increase by very few levels as compared to the other
(i.e. right).

AVL tree is a Balanced Binary Search tree. ( The name comes from the two
mathematicians, G.M. Adelson-Velskii, and E.M. Landis, who created it).
This means, AVL trees are Binary Search Trees in which height of any two
sub-trees (of any node) differ no more than one.

Requirement :
Consider normal Binary Search tree. For numbers inserted in the following order
45, 60, 12, 25, 65, 75, 55, 90, 110
the Binary Search Tree will be as follows,
4
5
1
2

6
0
2
5

6
5

5
5

BST for above numbers

7
5

9
0
11
0

To locate any key in the left sub-tree it takes maximum three attempts, and
to search any key in the right sub-tree it takes maximum six attempts.
The AVL tree for the above sequence of numbers will be as follows, which
will give better results for searching data.
4
5
1
2

6
5
2
5
5
5

Notes prepared by, Santosh Kabir.


Mobile : 98336 29398

9
0

6
0

27 of 36

7
5
1
1

11
0

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )

Thus, AVL tree is a Binary search tree which is either empty or always has
all sub-trees as AVL trees i.e. height balanced trees.
Balance factor of any tree is the difference between the height of the left
subtree and the height of right subtree.
In case of AVL trees the balance factor cant be greater than 1. i.e. balance
factor for AVL trees is 0, 1, -1.
From the balance factor of the tree one can use three different terms for
AVL trees: LH i.e. Left High, to indicate that the left subtree is higher, RH
i.e. Right High to indicate the right subtree is higher and EH i.e. Even High
to indicate that both subtrees have same height.

(In exam, for notes on AVL tree, write above part + any one or two balancing methods.)

Balancing an AVL tree: ( Rotating tree for Balancing )


Whenever we insert a node into a tree or delete a node from a tree, the resulting
tree may be unbalanced. We have to balance it to keep its structure intact.
Balancing of AVL tree is done by rotating nodes either towards left or right.
AVL tree has four different unbalanced status,

Single Rotation :
1) Left of Left:
The subtree of a Left High tree has become Left high. This type of tree is balanced
by rotating the out of balance node to the right. Lets insert a node 12 into a tree
with two nodes 20 and 18 as shown in fig.a below. In a simple example below we
rotate (out of balance) node 20 on right to balance the tree.
Inserting node 12

EH

Rotate right
2
0

LH

(a1)

1
8

1
2

Out of
balance
( left of left ) EH

After inserting 12
(a2) After rotation

1
8
1
2

2
0

EH

Now consider a following an example. Here, also a node 18 is rotated right to


balance the tree.
Inserting node 4
Rotate right
Out of
balance
( left of left )
LH

EH

1
2

4
8

1
8 EH
1
4

8
2
0

2
0

1
2
1

1
8

4
After inserting
4

Notes prepared by, Santosh Kabir.


Mobile : 98336 29398

28 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


In the process the node 12 becomes a root node and we attach its right sub-tree
14 to the left of 18.

2) Right of Right:
The subtree of a Right High tree has become Right high. e.g. insert a node 20 on
the right of right high tree (fig.a). Here, we rotate the root node 12 (which is
unbalanced) on the left to balance the tree. See the example below,

Rotation

1
8

RH

1
2

1
2

1
8

2
0

2
0
In the process the node 18 becomes the new root node. The left sub-tree of 18 is
connected as right subtree of old root (i.e.12)

Double Rotation :
In following two cases we require to rotate the tree twice to balance it.

3) Right of Left:

The subtree of a Left High tree has become Right high. We first consider simple example in
which tree is Left-high with only two nodes (12 and 4), and it its left sub-tree (here 4)
becomes right-high when a new node (here 8) is added.
To balance it we first rotate left sub-tree (which has become RH) to the left and then we
rotate the tree (here 12) to the right. See the example below,
Ex. 1

1
2

First
Rotation

1
2

Second
Rotation

8
8

Balanced (AVL)
tree

Inserting Node 8

Ex. 2

4
4

1
8
1
2

Original tree

2
0

2
3

Second
Rotate
18 right

2
3

First rotate
12 left

1
2

1
8

4
4

1
4
5
2

1
2

2
0
1
6

After left rotation


112

1
4

5
2

2
3

1
6

Inserting Node
Notes prepared 16
by, Santosh Kabir.
After right
Mobile : 98336 29398
29 of 36
rotation

1
4

4
4

4. Binary Trees

www.santoshkabirsir.com

1
2

1
8
1

5
2
2

DS - DSAA ( Common Topics )

4) Left of Right:
he subtree of a Right High tree has become Left high. Here the right subtree is rotated
towards right then we rotate its upper node (here root18) to left to balance the tree.
1
8
1
2

4
4

Original tree

1
8

Rotate left

Rotate right

1
2

2
3

5
2

2
3

4
4

2
0

5
2

2
0

2
3

Inserting Node
20

4
4

1
8
1
2

5
2

2
0

Example: Constructing an AVL tree for given month names (assume alphabetical
order). The names given are, MAR, MAY, JUN, JUL, JAN, FEB, AUS, SEP, NOV,
OCT, APR, DEC. The steps are shown below.
1. Add MAR,MAY,JUN, JULY

2. For adding JAN Rotate


JUN on Right

3. To Add FEB Rotate


MAR on Right

MA
MA

R
JUN

MA

JUL

MA

JUL

JUL

MA

JAN

JU
JAN

4. For adding AUG Rotate JAN on Right

FEB

JU

MA

5. Add SEP

JUL

JUL
MA

FEB

AU

FEB

R
JU
JAN

MA
R

MA
AU

Notes prepared by, Santosh Kabir.


Mobile : 98336 29398

30 of 36

JAN

JU

MA

4. Binary Trees
SEP

www.santoshkabirsir.com
em
ber

DS - DSAA ( Common Topics )

6. To Add NOV, Rotate SEP on Right first then Rotate MAY on Left
(6.a)

(6.b)

V
Y

Ve

NO
MAY
SEP
V
em
SEP
ber
em

mb

ber

SEP

NO

7. To Add OCT. first Rotate SEP on Right then Rotate of balance node MAR on Left
(7.a)

(7.b)

MA

(7.c)
NO

R
JUN

NO

JUL

V
MAY

FEB

SEP

JU

MA

8. Add APR, DEC

AU
SEP

JAN

MAY

SEP

Ne

em

em

JU

mb

ber

ber

er
NO

JAN

G
DEC

APR

OC

MA

G
JU

FEB

AU

NO
V

TY

OC
T

er

OC

MAR

MA

OC

Final AVL tree

JU

MAY

SEP

Ne

em

em

mb

ber

ber

er

Multi-way trees:
( Following two paragraphs are only for reading )
Binary trees ( Binary search tree, AVL trees etc) have nodes with maximum two subtrees, i.e. the
out-degree of each node is restricted to two. As the tree grows their height become significant. e.g. a
tree with 1000 entries has a height of at least 10. If the trees are un-balanced, their heights can be
significantly larger.
Multi-way tree retain some of the properties of Binary search trees, but its outdegree is not restricted
to 2. Also, every node in multiway tree will have multiple entries.
These are search trees, used in internal search trees, spelling checkers, and external file indexes.

m-Way search trees:


An m-way tree is search tree in which each node can have zero to m sub-trees, where m is defined
as order of the tree. Following are the properties of m-way tree.
1. Each node has 0 to m subtrees.
2. Given a node with k<m subtrees, the node contains k subtree links, and k-1 data entries.
3. The key-values in the first subtree are all less than the key in the first entry; the key-values
in the other sub-trees are all greater than or equal to the key in their parent entry.
4. The keys of the data-entries are ordered, key1 <= key2 <= key3 <= .. keyk
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

31 of 36

(6.c)
NO
MA

MA

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )

50

35

45

60

85

70

100

95

90

150

125

135

110

120

175

75

Figure below shows an example of a m-way tree with order four i.e. m=4.
(read as B trees )
The general multiway tree has a potential to greatly reduce the height of a tree.
However, it still has one major deficiency: it is not balanced. B-tree is an m-way
search tree with the following additional properties.
1. The root is either a leaf or has 2 to m subtrees.
2. All internal nodes have at least m/2 non-null subtrees and at most m nonnull subtrees.
3. All leaf nodes are the same level: i.e. the tree is perfectly balanced.
4. A leaf node has at least m/2 1 and at most m-1 entries.
Following figure shows a B-tree of order 5.

Inserting a entry into B-tree :


Like a binary search tree, the node is inserted in the B-tree at leaf node.
First step is to locate the leaf node for the data being inserted.
If the node is not full, i.e. if it has less than m-1 entries the new data is simply
inserted at the proper place in the node.
When the leaf node is full (called overflow condition), the node should be split into
two nodes, each containing half the entries. For this a new memory is allocated
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

32 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


for a new node. The entry is copied either into the new node or into the original
node (depending upon the key value). Then the median entry is inserted into the
parent node.
Thus, we can say that a B-tree grows from bottom up.
Following figure shows how a new value is inserted in a tree with only one node.
11

14

21

78

97

Full node

new data

(a) Ready to insert 97


11

14

21

78

original node

97

new node

(b) Create new right subtree

New tree

11

21

14

78

original node

97

new node

Since, the node is already full, before inserting 97 into it, we split the node and
median entry (here 21) should be copied to parent node at proper place. In the
process if overflow occurs at the parent node then it is also split and its median
value is copied to its parent node.
Since, here the current node is root node a new root node is created with entry
21.

Searching an entry:
(Refer to multiway node structure discussed in previous topics)
Search node first checks to see if the target is less than the first entry in the node.
If it is, then it reads the fPtr from the node. If the target is not less than the first
entry then to locate the targets node, it starts searching from last entry in the
node. If the target key is greater than any entry then right link in that entry is
read. The entry gives the link for the subtree to the right of the entry. This process
is continued till either the node is found or end of tree is located. If the key to be
searched is found the searching procedure should not only return the node
Notes prepared by, Santosh Kabir.
Mobile : 98336 29398

33 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


pointer but the entry index in which the key is located. This is commonly achieved
by using reference type of parameters.
1. Check the first entry in the current node.
a. If it is larger than the key, reads the first link i.e. link for the Left child of the current node.
Thus, search moves to next level.
2. Else go through all the entries from last to first in the node.
a. If an ith entry holds value less the key, then i+1th link gives link for the right child.
b. If entry found in the current node return its reference.
3. Repeat steps 1 and 2 for node with new link.

Delete entry from B-tree:


To delete an entry from the B-tree we first locate the entry in a tree. After the
entry is removed, if the node does have enough entries, we need to correct the
structural deficiency.
Since, B-tree is a like a binary search tree, all deletions are finally related to leaf nodes. After
deletion we have to find the data entry to replace it.
Following figure shows B-Tree deletion procedure.
Thus, deletion can be summarized as follows,
If the key is found in a leaf node, the key is deleted.
After deleting the entry, if the node is still at least half filled, then entries on the right (in the node) are
just shifted by one position towards left.
After deletion if node has lesser entries than required, then, entries from siblings are redistributed,
between this node, its siblings and parent node.
After deletion of node if the node has entries less than required entries, a node and its sibling can be
merged.

B-tree traversal:
Since B-tree is built on the basis of binary search tree, we can follow a procedure
like in-order traversal. The major difference is however that, except for the leaf
nodes, we dont process all the entries in a node at a time. Therefore we must
remember which entry was last processed whenever we return back to the node.
This, achieved using recursive procedure.
Traversal for a simple B-tree is shown below. The arrows shows the traversal path.
Start

11

14

19

Notes prepared by, Santosh Kabir.


Mobile : 98336 29398

20

34 of 36

end
21

58

42

45

63

74

87

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )


(short notes on B-Tree, write the points to describe B-tree, and then explain Inserting
node, searching etc. in short )

B+ Trees:
One of the drawbacks of the B-tree is the difficulty of traversing the keys (entries)
sequentially. A lot of processing time is required for moving up and down in the
tree structure.
Sometimes it is required to move through lot of entries sequentially.
A variation of B-tree structure, B+ tree retains the rapid random access
property of B-tree, while also allowing rapid sequential access.
In B+ trees all the keys are maintained in leaf nodes, and the keys are
replicated in non-leaf nodes to define paths for locating individual records.
The leaves are linked together to provide a sequential path for traversing
the keys in the tree.
Thus there are two differences between the B-trees and B+ trees.
1. Each data entry (key) must be represented at a leaf node. Internal nodes
just provide paths for searching keys.
2. Each leaf node has one additional pointer, which is to move to next leaf
node in sequence.
Example of a typical B+ tree is shown below,
To search a record associated with a key 53, the key is first compared with 98, i.e.
the key in root, since 53 is less, proceed to node B. Value 53 is compared with 36
and then 53 (sequentially). Since the value is less than or equal to 5, proceed to
node E.
Note that the search does not stop when the key was located in the internal node
B. In the B+ trees, the pointer s to records are only associated with the keys in
leaf nodes; consequently the search does not halt till the key is located in the leaf
node.

These notes are also available at :


www.santoshkabirsir.com

Notes prepared by, Santosh Kabir.


Mobile : 98336 29398

35 of 36

4. Binary Trees

www.santoshkabirsir.com

DS - DSAA ( Common Topics )

98

B
36
81

8 17
36

56

104
119

F
42
53

56
81

G
65

72

83
98

96

102
104

107 112
119

104
119

B+ Tree

----0000----

Sem IV - IT

Web Programming ( WP )
[ HTML, ASP.Net with C#, PHP, JSP, MySQL etc. ]
( Learn to design and develop small Internet based programs )

=====0000=====

Regular Batches at Andheri, Dadar, Thane

Santosh Kabir sir


Mobile :

98336 29398

www.santoshkabirsir.com

Notes prepared by, Santosh Kabir.


Mobile : 98336 29398

36 of 36

4. Binary Trees

www.santoshkabirsir.com

Anda mungkin juga menyukai