Download Chap 07 :: Trees

Document related concepts

Linked list wikipedia , lookup

Quadtree wikipedia , lookup

Lattice model (finance) wikipedia , lookup

B-tree wikipedia , lookup

Red–black tree wikipedia , lookup

Interval tree wikipedia , lookup

Binary tree wikipedia , lookup

Binary search tree wikipedia , lookup

Transcript
M7.1: Introduction:
A tree is a non-linear data structure in which items are arranged in a sorted
sequence. It is used to represent hierarchical relationship existing amongst several
data items.
We can define the tree as:
“A tree is a non-linear data structure which is a finite set of one or more nodes such
that”
1. there is a special designated node, called the root R of the tree
2. and its remaining nodes are partitioned into number of disjoint subsets (n>=0),
each of which is itself a tree, such as T1, T2, …., Tn. These are called as
subtrees.
(Fig M7.1: Examples of Tree data-structure)
Natural trees grow upwards from the ground into the air. But, tree data structure
grows downwards from top to bottom as shown in figure M7.1. It is an universally
practiced convention for trees.
Page 1
www.magix.in
M7.2: Tree Terminology:
Let’s first consider some of the basic terms that we need to know first if wanna know
the tree data structure further:
(Fig M7.2: Tree data structure)
1. Node:
Each data item in a tree is basically represented by a node. A tree node is a
collection of data information and branches (links) to other data items. Upper
figure M7.2 has 6 number of nodes.
]
2. Root Node:
There is always a designated node, called root node in a tree data structure.
It is the very first node in the hierarchical arrangement of tree nodes. In
following figure ‘A’ is the root node.
(Fig M7.3: Hierarchical structure of a tree)
3. Degree of a Node:
The number of subtrees (children) of a node is called its degree. In above
figure, the degree of A is 3, the degree of B is 1, the degree of C is 2, the
degree of D is one and the degree of H is 3.
4. Degree of a Tree:
The degree of a tree is the maximum of its element degrees. The degree of
a tree, shown in above figure is 3.
Page 2
www.magix.in
5. Leaf or Terminal or External Node:
Nodes that have zero degree are called as leaf nodes or terminal nodes. In
above figure, E, F, G, I, J and K are leaf nodes.
6. Non-Terminal or Internal Node:
Nodes that have one or more than one degree are called as non-terminal
nodes. In above figure A, B, C, D, and H are non-terminal nodes.
7. Sibling:
Children of the same parent are called as siblings. In above figure M7.3:
Ø B, C and D are siblings of node A
Ø F and G are siblings of C and I
Ø J and K are siblings of H.
8. Level:
Each node is assigned a level number in such a way that the root node is
always at level 1, its immediate children are at level 2 and their immediate
children are at level 3 and so on up to the leaf nodes. It means that if a node is
at ith level then its children are at (i+1)th level.
9. Height/ Depth of a Tree:
If level of the root is denoted by 1, then the maximum level number of the
tree is known as its ‘height’ or ‘depth’.
10. Subtree:
A subtree is a portion of a tree data structure that can be viewed as a
complete tree in itself. Any node in a tree ‘T’, together with all the nodes below
it, comprise a subtree of T. The subtree corresponding to the root node is the
entire tree; the subtree corresponding to any other node is called a proper
subtree.
11. Edge:
It is a connecting line of two nodes. That is, the line drawn from one node to
another node is called an ‘edge’.
12. Path:
It is a sequence of consecutive edges from the source node to the
destination node. In the above tree M7.3, the path between A and J is given by
the node pairs:
(A, D) , (D, H) and (H, J)
13. Forest:
It is a set of disjoint trees. In a given tree, if you remove its root node then it
becomes a forest. In the above tree M7.3, if we remove the root node ‘A’, there
is forest with three trees.
Page 3
www.magix.in
M7.3: Binary Tree:
In computer science, a binary tree is a tree data structure in which each node has at
most two children. Typically the first node is known as the parent and the child nodes
are called left and right.
The essential differences between a binary tree and a tree are:
Ø A binary tree can be empty whereas a tree cannot.
Ø Each element in binary tree has at most two subtrees (one or both of
these subtrees may be empty). Each element in a tree can have any
number of subtrees.
Ø The subtrees of each element in a binary tree are ordered. That is, we
distinguish between the left and right subtrees. The subtrees in a tree are
unordered.
Like a tree, a binary tree is drawn with its root at the top. The elements in the left
(/right) subtree of the root are drawn below and to the left (/right) of the root.
Between each element and its children is a line or edge.
(Fig M7.4: Some of the combinations for binary trees)
(Fig M7.5: Another example of binary tree with data nodes)
Page 4
www.magix.in
Some Properties of Binary Trees:
Property 1: A binary tree with ‘n’ elements, n>0, has exactly n-1 edges.
Proof:
Every element in a binary tree, except the root, has exactly one parent.
There is exactly one edge between each child and its parent. So the
number of edges is ‘n-1’.
Property 2: A binary tree of height ‘h’, h>0, has at least ‘h’ and at most 2h-1
Proof:
elements in it.
Since there must be at least one element at each level, the number of
elements is at least ‘h’. As each element can have at most two
children, the number of elements at level ‘k’ is at most 2k-1 for k>0.
For h=0, the total number of elements is 0, which equals 20-1. For
‘h>0’, the total number of elements cannot exceed :-
M7.4: Types of Binary Trees:
Binary trees are again classified in some categories on the base of their certain
characteristics. Let’s discuss some of them:
M7.4.1: Full Binary Tree:
A binary tree of height ‘h’ that contains 2h-1 elements is called a “full binary tree”.
The binary tree of figure M7.6(a) is a full binary tree whereas the binary tree of figure
M7.6(b) is not a “full binary tree”
Fig M7.6 (b) A binary tree which is not full.
Page 5
www.magix.in
M7.4.2: Complete Binary Tree:
A complete binary tree is a special case of a binary tree, in which all the levels,
except perhaps the last, are full; while on the last level, any missing nodes are to the
right of all the nodes that are present. For example, we could have:
Or
even this
But we don't want are trees like:
Page 6
www.magix.in
M7.4.3: Strictly Binary Tree:
A binary tree is strictly binary tree if every node in the tree is either 0 or 2, then the
tree is said to be “strictly binary tree”. i.e., each node can have maximum two
children or no children (no children indicate empty ‘left’ and empty ‘right’ child).
(Fig M7.7: An example of Strict binary tree)
M7.4.4: Tournament Tree/ Selection Tree:
Suppose ‘n’ players enters in a chess tournament and further suppose that the
tournament is played on knock-out basis. By knock-out basis means a player is
eliminated from the tournament upon losing a match. Pairs of players play each
other until only one remains undefeated. The undefeated player is declared winner of
the tournament. Following figure shows a possible tournament involving eight players
with some numeric numbering. The tournament is described by a binary tree in which
each external node (leaf node) represents a player and each internal node represents
a match played between players designated by the children of the node.
The tournament tree is described by a complete binary tree:
Ø Each external node represents a player
Ø Each internal node represents a match played
Ø Each level of internal nodes defines a round of matches
(Fig 7.8: 8 player tournament tree)
Page 7
www.magix.in
There are two types of tournament trees: ‘Winner trees’ and ‘loser trees’. The tree in
above figure are called “winner trees” because at each internal node, we record the
winner of the match played at that node. In contrast, if we record the loser of the
match played at that node, the tournament tree is called a “loser tree”. Tournament
trees are also called “selection trees”.
(Fig 7.9: 8 player loser tree)
M7.4.5: Binary Search Trees (BST):
A binary search tree ‘T’ is a binary tree that may be empty. A nonempty binary search
tree satisfy the following properties:
1. Every element has a key (or value) and no two elements have the same key.
i.e. all keys are unique.
2. The keys, if any, in the left subtree of the root are smaller than the key of
the root.
3. The keys, if any, in the right subtree of the root are larger than the key in the
root.
4. The left and right subtrees of the root are also binary search trees.
Let’s have some example for this. Following figures shows different possible
combination of BST with same key values:
Page 8
www.magix.in
(Fig 7.10: Examples of BST)
M7.5: Representation of Binary Trees and BST:
It is often required to maintain binary trees in the computer memory. There are two
traditional popular techniques that are used to maintain binary trees in the memory.
These are:
Ø Sequential representation
Ø Linked List representation
1. Sequential Representation:
A sequential representation of a binary tree requires numbering of nodes;
starting with nodes on level 1, then on level 2 and so on. The nodes are
numbered from left to right. One thing to notice is that numbering of nodes is
always done considering a complete binary tree. i.e. following figure shows the
numbering of a tree with height 4.
(Fig 7.11: Numbering of nodes in a binary tree)
Page 9
www.magix.in
Now the binary (or BST) tree is represented by storing each element at the array
position corresponding to the number assigned. In this representation, a binary
(search) tree having ‘n’ levels may require an array of size (2n-1). For simplicity, we
will consider that array is indexed with an index set beginning from 1 not from 0.
Now let’s take an example:
can be represented in a array as:
Lets take another example:
(Fig 7.12: Example for array representation of binary tree)
Page 10
www.magix.in
Now imagine how the following binary search tree will stored in array representation:
(a) A right-skewed binary search tree
The array representation of binary search tree of above figure is shown in following
figure:
(Fig 7.13: b: Array representation of upper BST)
This scheme of representation is quite wasteful of space when the binary (or BST)
tree is skewed or number of elements is small as compared to its height.
Hence, array representation is useful only when the binary (or BST) tree is full or
complete.
2. Link-List Representation:
The most popular and practical way of representing a binary (or BST) tree is
using linked-list (pointers).
For example, the binary tree:
(a) A binary tree
Page 11
www.magix.in
Can be represented using linked list as:
And the tree
can be represented in linked list form as:
In linked representation, each element is represented by a node that has exactly two link
fields. Let us call these fields ‘left’ and ‘right’. In addition to these two link fields, each node
has a data field called ‘info’.
This node structure is defines as :
struct nodeType
{
struct nodeType *left ;
int info ;
struct nodeType *right ;
};
Page 12
www.magix.in
Each node in the drawing of a binary tree is represented by a pointer from the parent
node to the child node. This pointer is placed in the appropriate link field of the
parent node. Since an ‘n’ element binary tree has exactly ‘n-1’ edges, there will be
2n-(n-1) = n+1 link fields that have NULL values (pictured as X).
In addition to the above node structure, a pointer variable, say ‘root’, is used to keep
track of the root of the binary tree. We can access all the nodes in binary tree starting
at the root and following ‘left’ and ‘right’ links.
M7.6: Creation of an BST:
Q.-> Draw a binary search tree for the following string considering each character as
information of the node in a binary search tree:
COMPUTER
Solution:
Initially the BST (Binary Search Tree) is empty. First character from the string is ‘C’. It
becomes the root of the tree. So, the BST is:
C
Next character from the string is ‘O’. This character is compared with the root
character ‘C’, it is greater than ‘C’. As the right pointer of ‘C’ node is NULL. The node
with information ‘O’ becomes the right node of ‘C’. So, the BST now is:
C
O
Next character is ‘M’. This character is compared with ‘C’. ‘M’ is greater than ‘C’. Right
pointer of ‘C’ is not equal to NULL. So ‘M’ is compared with ‘O’. Now ‘M’ is less than
‘O’ and the left pointer ‘O’ is NULL, so the node with information ‘M’ becomes left
node of ‘O’. So, the BST is:
C
O
M
Page 13
www.magix.in
Next character is ‘P’. This character is first compared with the root information of
BST. It is greater than root information that is ‘C’. It is also greater than the right node
information ‘O’. As the right pointer of ‘O’ is NULL, the node that is to be inserted in
BST becomes the right node of ‘O’. So, now the BST is:
C
O
P
M
The next character is ‘U’. It is greater than ‘C’, ‘O’ and ‘P’. The right pointer of node
with information ‘P’ is equal to NULL, so the new node with information ‘U’ is inserted
as the right node of ‘P’. So, the BST becomes:
C
O
P
M
U
The next character is ‘T’. It is greater than ‘C’, ‘O’, and ‘P’ but less than ‘U’. The left
pointer of node ‘U’ is NULL, so the new node with information ‘T’ is inserted to the left
of ‘U’. So, the BST becomes:
C
O
M
P
U
T
Page 14
www.magix.in
The next character is ‘E’. It is greater than ‘C’, less than ‘O’ and less than ‘M’. The left
pointer of the node ‘M’ is NULL, so the new node with information ‘E’ is inserted as
left node of ‘M’. So the BST becomes:
C
O
P
M
U
E
T
The next and last character is ‘R’. It is greater than ‘C’, ‘O’, and ‘P’ but less than ‘U’
and ‘T’. The left pointer of ‘T’ is equal to NULL, so the last new node with information
‘R’ becomes the left node of ‘T’. So, the final BST is:
C
O
P
M
U
E
T
R
Q.2: Draw a binary search tree considering the month name as the information of a
binary search tree node, for the following list of month names of year:
Jun, Sep, Jan, Mar, Feb, Dec, Aug, Oct, Nov, Jul, May, Apr
Solution:
The order of month-name is Jan, Feb, Mar etc. The first name in the list is ‘Jun’.
It is the root of the binary search tree. The next name is ‘Sep’; it is compared with the
root node, which is greater than root node, so it forms the right node of root. Similarly
all the elements are compared and inserted into the binary search tree at proper
places. Step by step drawing of the binary search tree is as follows:
Page 15
www.magix.in
Page 16
www.magix.in
M7.7: Common Operations on Binary Trees & BSTs:
Some of the operations that are commonly performed on binary as well as binary
search trees are:
1. Create an empty tree
2. Traverse it.
3. Determine its height
4. Determine the number of elements in it.
5. Determine the number of internal nodes i.e. non-leaf nodes.
6. Determine the number of external nodes i.e. leaf nodes.
7. Remove it from memory.
Page 17
www.magix.in
The following are some the operations having relevance to only binary Search trees:
1. Insert a new node/element.
2. Search an element.
3. Find the smallest element.
4. Find the largest element.
5. Delete a node.
In our implementation of binary (or BST) tree, we will consider following declarations:
typedef struct nodeType
{
struct nodeType *left ;
int info ;
struct nodeType *right ;
} BST ;
BST *root ;
Here, we have defined a new data type and given it a name BST, then we have
declared a pointer variable ‘root’ to represent the binary (search) tree.
M7.7.1: Creating an Empty Binary (Search) Tree:
Since the binary (Search) tree will be empty in the beginning, the variable ‘root’ is
assigned a sentinel value to indicate that binary (search) tree is empty. The following
listing shows the implementation of this function:
void CreateTree ( BST **tree)
{
*tree = NULL ;
}
M7.7.2: Traversing Binary (Search) Tree:
Traversing means visiting each node exactly once. A full traversal of a binary tree ‘T’
produces a linear order of elements existing in ‘T’. There are three basic ways for
traversing a binary tree:
1. Pre-Order traversal:
The traversal order is:
Ø Process the root R
Ø Traverse the left subtree of R in pre-order
Ø Traverse the right subtree of R in pre-order
2. In-Order traversal:
The traversal order is:
Ø Traverse the left subtree of R in In-order
Ø Process the root R
Ø Traverse the right subtree of R in In-order
Page 18
www.magix.in
3. Post-Order traversal:
The traversal order is:
Ø Traverse the left subtree of R in post-order
Ø Traverse the right subtree of R in post-order
Ø Process the root R
In addition to above standard traversal schemes, there is another possible traversal
scheme known as “Level-order traversal”. As its name suggests, in this scheme first
node at level 1, i.e., root is traversed, then nodes at level2 followed by nodes at
level3, … , and so on.
Example:
Consider the following binary tree T:
In this binary tree:
a)
Preorder traversal yields:
b)
Post-order traversal yields:
c)
In-order traversal yields:
d)
level-order traversal yields:
a)
2, 7, 2, 6, 5, 11, 5, 9, 4
2, 5, 11, 6, 7, 4, 9, 5, 2
2, 7, 5, 6, 11, 2, 5, 4, 9
2, 7, 5, 2, 6, 9, 5, 11, 4
Pre-Order Traversal of a Binary (Search) Tree:
Following listing shows the recursive implementation of pre-order traversal algorithm:
void preorderTraversalRecursive ( BST *tree )
{
if ( tree != NULL )
{
printf( “ %d ”, tree -> info ) ;
preorderTraversalRecursive ( tree -> left ) ;
preorderTraversalRecursive ( tree -> right ) ;
}
}
Page 19
www.magix.in
Algorithm for pre-order recursive:
Algorithm PreOrderRecursive (PTR)
Here PTR is a pointer contains the address of root node.
Step1:
Begin
Step2:
if (PTR <> NULL) then
Step2.1:
Write: PTR -> info
Step2.2:
Call PreOrderRecursive (PTR-> LEFT)
Step2.3:
Call PreOrderRecursive (PTR-> RIGHT)
Step2.4:
Endif
Step3:
End
b)
In-Order Traversal of a Binary (Search) Tree:
The following listing shows the recursive implementation of in-order traversal algorithm:
void inorderTraversalRecursive ( BST *tree)
{
if ( tree != NULL )
{
inorderTraversalRecursive ( tree -> left ) ;
printf ( “ %d “ , tree -> info ) ;
inorderTraversalRecursive ( tree -> right ) ;
}
}
Algorithm for In-order recursive:
Algorithm InOrderRecursive (PTR)
Here PTR is a pointer contains the address of root node.
Step1:
Begin
Step2:
if (PTR <> NULL) then
Step2.1:
Call InOrderRecursive (PTR-> LEFT)
Step2.2:
Write: PTR -> info
Step2.3:
Call InOrderRecursive (PTR-> RIGHT)
Step2.4:
Endif
Step3:
End
c)
Post-Order Traversal of a Binary (Search) Tree:
Following listing shows the recursive implementation of post-order traversal algorithm:
void postorderTraversalRecursive ( BST *tree )
{
if ( tree != NULL )
{
postorderTraversalRecursive ( tree -> left ) ;
postorderTraversalRecursive ( tree -> right ) ;
printf( “ %d ”, tree -> info ) ;
}
}
Page 20
www.magix.in
Algorithm for post-order recursive:
Algorithm PostOrderRecursive (PTR)
Here PTR is a pointer contains the address of root node.
Step1:
Begin
Step2:
if (PTR <> NULL) then
Step2.1:
Call PostOrderRecursive (PTR-> LEFT)
Step2.2:
Call PostOrderRecursive (PTR-> RIGHT)
Step2.3:
Write: PTR -> info
Step2.4:
Endif
Step3:
End
d)
Level-Order Traversal of a Binary (Search) Tree:
The following listing shows the implementation of level-order traversal algorithm:
void levelorderTraversal ( BST *tree )
{
queue *q ;
BST *ptr ;
createQueue ( &q ) ;
enqueue ( &q , tree ) ;
while ( ! isEmpty ( q ) )
{
ptr = dequeue ( &q ) ;
if ( ptr -> left != NULL )
enqueue ( &q, ptr -> left ) ;
if ( ptr -> right != NULL )
enqueue ( &q , ptr -> right ) ;
printf ( “ %d “ , ptr -> info ) ;
}
}
Algorithm for level-order traversal:
Algorithm LevelOrderTraversal (Tree)
Here TREE is a pointer contains the address of root node. It use a queue ‘q’ whose elements are
pointers to type BST. It uses a temporary pointer variable ‘ptr’ to hold the address of current node.
Step1:
Begin
Step2:
CreateEmptyQueue (q) //Call procedure to create an empty queue
Step3:
enqueue ( q, tree )
// enqueu NULL value as sentinel value
Step4:
While ( q is not Empty ) do
Step4.1:
Set ptr := dequeue ( q )
Step4.2:
if ( ptr -> left != NULL ) then
Step4.2.1:
enqueue ( q, ptr -> left )
Step4.2.2:
End if
Step4.3:
if ( ptr -> right != NULL )
Step4.3.1:
enqueue ( q, ptr -> right )
Step4.3.2:
end if
Step4.4:
Print : ptr -> info
Step4.5:
End while
Step5: End
Page 21
www.magix.in
Construction of Binary Tree:
Binary tree has one very interesting property – property is that if we are given “inorder traversal” and either of “pre-order” or “post-order” traversals, we can construct
the binary tree from these traversals.
Example:
Consider that a binary tree ‘T’ has 8 nodes. The pre-order and in-order traversals of
binary tree ‘T’ yield the following sequence of nodes:
Pre-order :
In – Order :
A
D
B
B
D
G
E G
E H
H
A
C
C
F
F
Draw the binary tree.
Solution:
The binary tree ‘T’ is drawn as follows:
The first node in the pre-order traversal is always a root node of the binary tree.
Thus the root node of the binary tree T is node ‘A’.
After determining the root node of the binary tree, our aim is to find the nodes
that comprise the left subtree and right subtree of node ‘A’. We know from the
in-order traversal that first left subtree is traversed, then root node, and finally
the right subtree. Thus all the nodes to the left of node ‘A’ in in-order traversal
comprise its left subtree. Similarly, all the nodes to the right of node ‘A’ in inorder traversal comprise its right subtree.
The above procedure partitions the pre-order and in-order traversal sequences
as shown below:
Page 22
www.magix.in
Following figure shows the partial binary tree constructed so far:
In the same way, we can construct the left subtree LTB and right subtree RTB. Let us
first consider the left subtree LTA. The pre-order and in-order traversal sequences of
the left subtree LTA are:
Pre-order:
B
D
E
G
H
In-Order :
D
B
G
E
H
From these traversal sequences we find that the root of the subtree is node B, and its
left subtree consists of a single node D and the right subtree consists of nodes G, E,
and H.
The above procedure partitions the pre-order and in-order sequences as shown
below:
Following figure shows the partial binary tree constructed so far:
Page 23
www.magix.in
Now consider the right subtree RTB. The pre-order and in-order traversal sequences of
RTB are:
Pre-order:
E
G
H
In-order:
G
E
H
From these traversal sequences we find that the root of the subtree RTB is node ‘E’,
and its left subtree consists of a single node ‘G’ and the right subtree also consists of
a single node ‘G’.
The above procedure partitions the pre-order and in-order traversal sequences of RTB
as shown below:
Following figure shows the partial binary tree constructed so far:
Thus we have completed the construction of the left subtree LTA of node ‘A’, which
was the root node of the binary tree.
Page 24
www.magix.in
Now we are left with the right subtree RTA. The pre-order and in-order traversal sequences of
RTA are:
Pre-order:
C
F
In-order:
C
F
From these traversal sequences we find that the root of the subtree RTA is node ‘C’, and its
left subtree is empty and the right subtree consists of a single node ‘F’.
The above procedure partitions the pre-order and in-order traversal sequences of RTA as
shown below:
Following figure shows the binary tree after this step, and this is the final binary tree:
(Final binary tree)
Note:
The above procedure can be easily modified if the in-order and the post-order traversals of a
binary tree are given. The only difference is that the root of the tree will be appearing as the last
node in the post-order traversal.
Exercise:
Consider that a binary tree ‘T’ has 8 nodes. The post-order and in-order traversals of binary tree ‘T’
yield the following sequence of nodes:
In – Order :
D B G E H
A
C
F
Post-order :
D G H E B
F
C
A
Draw the binary tree.
Page 25
www.magix.in
M7.7.3: Determining Height of Binary (Search) Tree:
In order to determine the height of a binary (search) tree, we find the height of
the ‘left subtree’ and ‘right subtree’ of a given node. The height of the binary
(search) tree at a given node will be equal to maximum height of the left and
right subtrees plus 1. The following listing shows the implementation of the
various steps required:
int determineHeight (BST *tree)
{
int leftHeight, rightHeight ;
if ( tree == NULL )
return 0 ;
else
{
leftHeight = determineHeight ( tree -> left ) ;
rightHeight = determineHeight ( tree -> right ) ;
if ( leftHeight > rightHeight )
return ++leftHeight ;
else
return ++rightHeight ;
}
}
Algorithm for Determining height of a bst:
Algorithm DetermineHeight (Tree)
Here TREE is a pointer contains the address of root node.
Step1:
Begin
Step2:
If ( Tree is NULL)
Step2.1:
Return 0
Step3:
Else
Step3.1:
Leftheight = Call DetermineHeight( tree->left)
Step3.2:
Rightheight = Call DetermineHeight( tree->right)
Step3.3:
if ( Leftheight > Rightheight )
Step3.3.1:
Return Leftheight+1
Step3.4:
else
Step3.4.1:
Return Rightheight+1
Step3.4.2:
end if
Step3.5:
End If
Step4:
END
Page 26
www.magix.in
M7.7.4: Determining Number of Nodes/ Elements in a Binary (Search) Tree:
The number of elements/Nodes in a binary (search) tree is equal to the number
of nodes in the ‘left subtree’ plus number of nodes in the ‘right subtree’ of a
given node plus 1. If the binary (search) tree is empty, then the number of
nodes is equal to 0. The following listing shows the implementation of the
various steps required for this approach:
int TotalNodes ( BST *tree )
{
if ( tree == NULL )
return 0 ;
else
return ( TotalNodes ( tree->left) + TotalNodes ( tree-> right) + 1 ) ;
}
Algorithm for Determining number of nodes in a bst:
Algorithm TotalNodes (Tree)
Here TREE is a pointer contains the address of root node.
Step1: Begin
Step2:
If ( Tree is NULL)
Step2.1:
Return 0
Step3:
Else
Step3.1:
Return ( TotalNodes(tree->left) + TotalNodes(tree->right) + 1 )
Step3.2: End If
Step4: END
M7.7.5: Determining Number of Internal Nodes in a Binary (Search) Tree:
The number of internal elements/Nodes in a binary (search) tree is equal to the
number of internal/non-leaf nodes in the ‘left subtree’ plus number of non-leaf
nodes in the ‘right subtree’ of a given node plus 1. If the binary (search) tree is
empty, then the number of internal nodes is equal to 0. The following listing
shows the implementation of the various steps required for this approach:
int internalNodes ( BST *tree )
{
if ( ( tree == NULL ) || ( ( tree->left == NULL) && (tree->right == NULL) ) )
return 0 ;
else
return ( internalNodes ( tree->left) + internalNodes ( tree-> right) + 1 ) ;
}
Page 27
www.magix.in
Algorithm for Determining number of internal nodes in a bst:
Algorithm InternalNodes (Tree)
Here TREE is a pointer contains the address of root node.
Step1:
Begin
Step2:
If ( ( Tree is NULL) OR (tree->left AND tree->right is NULL) )
Step2.1:
Return 0
Step3:
Else
Step3.1:
Return ( InternalNodes(tree->left) + InteranalNodes(tree->right) + 1 )
Step3.2:
End If
Step4:
END
M7.7.6: Determining Number of External Nodes in a Binary (Search) Tree:
The number of external elements/Nodes in a binary (search) tree is equal to the sum
of the external in the left subtree and the external nodes in the right subtree of a
given node. Note that if the binary (search) tree is empty then the number of external
nodes is 0 and if there is only one node in the binary (search) tree then the number of
external node is equal to 1. The following listing shows the implementation of the
various steps required for this approach:
int externalNodes ( BST *tree )
{
if( tree== NULL )
return 0 ;
else if ( ( tree->left == (BST *)NULL) && (tree->right==(BST *) NULL) )
return 1 ;
else
return ( externalNodes ( tree->left) + externalNodes ( tree-> right) ) ;
}
Algorithm for Determining number of external nodes in a bst:
Algorithm externalNodes (Tree)
Here TREE is a pointer contains the address of root node.
Step1:
Begin
Step2:
If ( Tree is NULL )
Step2.1:
Return 0
Step2.2:
Else if ( tree->left AND tree -> right is NULL)
Step2.2.1:
Return 1
Step2.3:
Else
Step2.3.1:
Return ( externalNodes(tree->left) + externalNodes(tree->right) )
Step2.4:
End If
Step3:
END
Page 28
www.magix.in
M7.7.7: Removing Binary (Search) Tree from memory:
Before a program using binary (search) tree represented using linked representation
terminates, the binary (search) tree must be removed from memory. To accomplish
this task, first we delete the left subtree and then right subtree and then node,
recursively. The following listing shows the implementation of the various steps
required:
void removeTreeFromMemory ( BST **tree )
{
if ( *tree != NULL )
{
removeTreeFromMemory (& (*tree ) -> left ) ;
removeTreeFromMemory (& (*tree ) -> right ) ;
free( *tree ) ;
}
}
Algorithm for Removing binary (search) tree from memory:
Algorithm removeFromMemory (Tree)
Here TREE is a pointer contains the address of root node.
Step1:
Begin
Step2:
If ( Tree is NOT NULL )
Step2.1:
removeFromMemory ( tree -> left )
Step2.2:
removeFromMemory ( tree -> right )
Step2.3:
freeNode( tree )
Step2.4:
End if
Step3:
END
TILL NOW WE HAVE SEEN OPERATION THAT ARE COMMON TO
NORMAL BINARY TREES AND BINARY SEARCH TREES. NOW WE
WILL DISCUSS SOME OF THE OPERATIONS THAT WILL WORK
ONLY FOR BINARY SEARCH TREE. SO DON’T TRY TO RUN
FOLLOWING OPERATIONS ON SIMPLE BINARY TREES.
M7.7.8: Inserting a new element in the Binary Search Tree (BST) :
If the binary search tree is initially empty, then the element is inserted as root node;
otherwise the new element is inserted as a terminal node. If the element is less than
the element in the root node, then the new element is inserted in the left subtree
else right subtree.
Consider the BST shown below:
Page 29
www.magix.in
Suppose the node pointed to by temp (with item 140) has to be inserted. The item
140 is compared with root node 100. Since it is greater, the right subtree of root
node has to be considered. Now compare 140 with 200 and since it is less, consider
the left subtree of the node 200. Now, compare 140 with 150. Since it is less,
consider the left subtree of node 150. Since, left subtree of node 150 is empty; the
node containing the item 140 has to be inserted towards left of a node 150. Thus, to
find the appropriate place and insert an item, the search should start from the root
node. The following listing shows the implementation of the various steps required:
void insertElementIterative ( BST **tree , int element )
{
BST *ptr, *nodePtr, *parentPtr ;
ptr = (BST * ) malloc ( sizeof(BST) ) ;
ptr -> info = element ;
ptr -> left = ptr -> right = NULL ;
if ( *tree == NULL )
*tree = ptr ;
else
{
parentPtr = NULL ;
nodePtr = *tree ;
while ( nodePtr != NULL )
{
parentPtr = nodePtr ;
if ( element < nodePtr->info )
nodePtr = nodePtr -> left ;
else
nodePtr = nodePtr -> right ;
}
if ( element < parentPtr -> info )
parentPtr -> left = ptr ;
else
parentPtr -> right = ptr ;
}
}
Page 30
www.magix.in
Algorithm for Inserting a New Element:
Algorithm InsertElement (Tree, element)
Here TREE is a pointer contains the address of root node.
Step1:
Begin
Step2:
Step3:
Step4:
Step5:
Step5.1:
Step5.2:
Step5.2.1:
Step5.2.2:
Step5.2.3:
Step5.2.3.1:
Step5.2.3.2:
Step5.2.3.2.1:
Step5.2.3.3:
Step5.2.3.3.1:
Step5.2.3.4:
Step5.2.4:
Step5.3:
Step6:
END
create empty nodes ‘ptr’, ‘nodePtr’, ‘parentPtr’
Set ptr ->info := element
Set ptr -> left := ptr -> right := NULL
if ( tree is NULL )
Set tree := ptr
else
Set parentPtr := NULL
Set nodePtr := tree
while ( nodePtr is NOT NULL )
Set parentPtr := nodePtr
if ( element < nodePtr->info )
Set nodePtr := nodePtr -> left
else
Set nodePtr := nodePtr -> right
End if
end while
end if
M7.7.9: Searching an element in the Binary Search Tree (BST) :
The element in a binary search tree can be searched very quickly. The search
operation on binary search tree is similar to applying binary search technique to a
sorted linear array. The element to be searched is compared with the root node. If it
matches with the root node, then search terminates here; otherwise the search is
continued in the left subtree of the node if the element is less than the root node or
in the right subtree if the element is greater than the root node.
The following listing shows the recursive implementation of the various steps
required:
BST *searchElementRecursive ( BST *tree, int value )
{
if ( ( tree -> info == value ) || ( tree == NULL ) )
return tree ;
else if ( value < tree->info )
return searchElementRecursive ( tree->left, value ) ;
else
return searchElementRecursive ( tree->right, value ) ;
}
Page 31
www.magix.in
Algorithm for Searching an element in the binary search tree:
Algorithm searchElement (Tree, value)
Here TREE is a pointer contains the address of root node.
Step1:
Begin
Step2:
If ( ( Tree->info =value ) OR ( Tree is NULL ) )
Step2.1:
return tree
Step2.2:
Else if ( value < Tree->info )
Step2.3:
return searchElement ( tree->left, value )
Step2.4:
Else
Step2.5:
return searchElement ( tree->right, value )
Step2.6:
End if
Step3:
END
M7.7.10: Finding the smallest element in the Binary Search Tree (BST) :
Because of the order property of binary search tree, the smallest node in the tree will
be one of the nodes in the left subtree, if it exists; otherwise the node itself will be
the smallest node. The following listing shows the various steps required for
implementation of this algo:
BST *findSmallestElement ( BST *tree )
{
if ( ( tree == (BST *) NULL) || (tree->left == (BST *) NULL ) )
return tree;
else
return findSmallestElement ( tree -> left ) ;
}
Algorithm for finding smallest node in the binary search tree:
Algorithm findSmallest (Tree)
Here TREE is a pointer contains the address of root node.
Step1:
Begin
Step2:
If ( ( Tree is NULL ) OR ( Tree->left is NULL) )
Step2.1:
return tree
Step2.2:
Else
Step2.3:
return findSmallest ( tree -> left )
Step2.4:
End if
Step3: END
Page 32
www.magix.in
M7.7.11: Finding the largest element in the Binary Search Tree (BST) :
Because of the order property of binary search tree, the largest node in the tree will
be one of the nodes in the right subtree, if it exists; otherwise the node itself will be
the largest node. The following listing shows the various steps required for
implementation of this algorithm:
BST *findLargestElement ( BST *tree )
{
if ( ( tree == (BST *) NULL) || (tree->right == (BST *) NULL ) )
return tree;
else
return findLargestElement ( tree -> right ) ;
}
Algorithm for finding smallest node in the binary search tree:
Algorithm findLargest (Tree)
Here TREE is a pointer contains the address of root node.
Step1:
Begin
Step2:
If ( ( Tree is NULL ) OR ( Tree->right is NULL) )
Step2.1:
return tree
Step2.2:
Else
Step2.3:
return findLargest ( tree -> right )
Step2.4:
End if
Step3: END
M7.7.12: Deleting a node from the Binary Search Tree (BST) :
It is very important to remember that once the required node is found and deleted, in
a binary search tree the ordering of the tree should be maintained i.e., even after
deleting a node, elements in the left subtree should be lesser and elements in the
right subtree should be greater than. To delete a node, the following possibilities may
arise:
Ø Case 1: node is terminal node – in this case, if the node is left child of its
parent, then the left pointer of its parent is set to NULL; otherwise it will be
right child of its parent and accordingly the pointer of its parent is set to NULL.
Ø Case 2: node having only one child – In this case, the appropriate pointer of its
parent is set to its child, thus by passing it.
Ø Case 3: node having two children – Its predecessor replaces the node value,
and then the predecessor of the node is deleted.
Combining these three cases, the entire procedure for deleting a node can be
implemented recursively as shown in the following listing:
Page 33
www.magix.in
void deleteNode ( BST **tree, int element )
{
BST *temp ;
if ( *tree == NULL )
{
printf ( “\n Element not found” ) ;
}
else if ( element < (*tree)->info )
deleteNode ( & ( ( *tree ) -> left ), element ) ;
else if ( element > (*tree)-> info )
deleteNode ( & ( ( *tree ) -> right ), element ) ;
else if ( (*tree) -> left && ( *tree ) -> right )
{
temp = findLargestNode ( ( *tree) -> left ) ;
( *tree ) -> info = temp ->info ;
deleteNode ( & ((*tree) ->left) , temp->info ) ;
}
else
{
temp = *tree ;
/* terminal node */
if ( ( *tree) -> left == NULL ) && ( ( *tree) -> right == NULL ) )
*tree = (BST *) NULL ;
else if ( ( *tree) -> left != NULL )
/*left child only */
*tree = ( *tree) -> left ;
else
/* right child only */
*tree = ( *tree) -> right ;
free (temp);
}
}
Algorithm for Deleting a node:
Algorithm deleteNode (Tree, element)
Here TREE is a pointer contains the address of root node.
Step1:
Begin
Step2:
if ( Tree is NULL)
Step2.1:
Exit
Step2.2:
else if ( element < Treeàinfo )
Step2.2.1:
deleteNode ( Treeàleft , element )
Step2.3:
else if ( element > Treeàright )
Step2.3.1:
deleteNode ( Treeàright , element )
Page 34
www.magix.in
Step2.4:
else if ( Treeàleft AND Treeàright )
Step2.4.1:
temp = LargestNode ( Treeà left )
Step2.4.2:
Set Treeàinfo := tempàinfo
Step2.4.3:
deleteNode ( Tree àleft , temp à info )
Step2.5:
else
Step2.5.1:
Set temp := Tree
Step2.5.2:
if ( Treeàleft and Treeàright is NULL )
Step2.5.2.1:
Set Tree := NULL
Step2.5.3:
else if ( Tree à left exists)
Step2.5.3.1:
Set Tree := Treeàleft
Step2.5.4:
else
Step2.5.4.1:
Set Tree := Treeàright
Step2.5.5:
end if
Step2.5.6:
freeNode ( temp )
Step3:
end if
Step4:
END
>> A Full length example program for tree implementation is given follows:
Program to illustrate the implementation of tree using
link-list :
/*
* Program to illustrate the implementation of different operations
* discussed above on a Binary Search Tree
*/
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
typedef struct BST_node
{
struct BST_node *left ;
int item ;
struct BST_node *right ;
} BST ;
void createTree (BST **tree)
{
*tree = NULL ;
}
Page 35
www.magix.in
void insertElementIterative( BST **tree , int element )
{
BST *ptr, *nodePtr, *parentPtr ;
ptr = (BST * ) malloc ( sizeof(BST) ) ;
ptr -> item = element ;
ptr -> left = ptr -> right = NULL ;
if ( *tree == NULL )
*tree = ptr ;
else
{
parentPtr = NULL ;
nodePtr = *tree ;
while ( nodePtr != NULL )
{
parentPtr = nodePtr ;
if ( element < nodePtr->item )
nodePtr = nodePtr -> left ;
else
nodePtr = nodePtr -> right ;
}
if ( element < parentPtr -> item )
parentPtr -> left = ptr ;
else
parentPtr -> right = ptr ;
}
}
void preorderTraversalRecursive (BST *tree)
{
if(tree != NULL)
{
printf(" %d", tree->item );
preorderTraversalRecursive(tree->left);
preorderTraversalRecursive(tree->right);
}
}
void inorderTraversalRecursive (BST *tree)
{
if(tree != NULL)
{
inorderTraversalRecursive(tree->left);
printf(" %d", tree->item);
inorderTraversalRecursive(tree->right);
}
}
Page 36
www.magix.in
void postorderTraversalRecursive (BST *tree)
{
if(tree != NULL)
{
postorderTraversalRecursive(tree->left);
postorderTraversalRecursive(tree->right);
printf(" %d", tree->item);
}
}
BST *searchElementRecursive ( BST *tree, int value )
{
if ( ( tree -> item == value ) || ( tree == NULL ) )
return tree ;
else if ( value < tree->item )
return searchElementRecursive ( tree->left, value ) ;
else
return searchElementRecursive ( tree->right, value ) ;
}
BST *findSmallestElement ( BST *tree )
{
if ( ( tree == (BST *) NULL) || (tree->left == (BST *) NULL ) )
return tree;
else
return findSmallestElement ( tree -> left ) ;
}
BST *findLargestElement ( BST *tree )
{
if ( ( tree == (BST *) NULL) || (tree->right == (BST *) NULL ) )
return tree;
else
return findLargestElement ( tree -> right ) ;
}
Page 37
www.magix.in
void deleteNode ( BST **tree, int element )
{
BST *temp ;
if ( *tree == NULL )
{
printf ("\n Element not found" ) ;
}
else if ( element < (*tree)->item )
deleteNode ( & ( ( *tree ) -> left ), element ) ;
else if ( element > (*tree)-> item )
deleteNode ( & ( ( *tree ) -> right ), element ) ;
else if ( (*tree) -> left && ( *tree ) -> right )
{
temp = findLargestElement( (*tree)->left ) ;
( *tree ) -> item = temp ->item ;
deleteNode ( & ((*tree) ->left) , temp->item ) ;
}
else
{
temp = *tree ;
/* terminal node */
if ( ( *tree)->left == NULL && (*tree)-> right == NULL )
*tree = (BST *) NULL ;
else if ( ( *tree) -> left != NULL )
/*left child only */
*tree = ( *tree) -> left ;
else
/* right child only */
*tree = ( *tree) -> right ;
free (temp);
}
}
int TotalNodes( BST *tree )
{
if ( tree == NULL )
return 0 ;
else
return ( TotalNodes ( tree->left) + TotalNodes ( tree-> right) + 1 ) ;
}
int externalNodes ( BST *tree )
{
if( tree== NULL )
return 0 ;
else if ( ( tree->left == (BST *)NULL) && (tree->right==(BST *) NULL) )
return 1 ;
else
return ( externalNodes ( tree->left) + externalNodes ( tree-> right) ) ;
}
Page 38
www.magix.in
int internalNodes ( BST *tree )
{
if ( ( tree == NULL ) || ( ( tree->left == NULL) && (tree->right == NULL) ) )
return 0 ;
else
return ( internalNodes ( tree->left) + internalNodes ( tree-> right) + 1 ) ;
}
int determineHeight(BST *tree)
{
int leftHeight, rightHeight ;
if ( tree == NULL )
return 0 ;
else
{
leftHeight = determineHeight ( tree -> left ) ;
rightHeight = determineHeight ( tree -> right ) ;
if ( leftHeight > rightHeight )
return ++leftHeight ;
else
return ++rightHeight ;
}
}
void removeTreeFromMemory ( BST **tree )
{
if ( *tree != NULL )
{
removeTreeFromMemory (& (*tree ) -> left ) ;
removeTreeFromMemory (& (*tree ) -> right ) ;
free( *tree ) ;
}
}
void main (void)
{
int choice, element, height ;
BST *root, *loc ;
createTree (&root);
while(1)
{
clrscr( );
Page 39
www.magix.in
printf("\n Options available \n");
printf("++++++++++++++++++++++++++++++++\n");
printf(" 1. Insert node \n");
printf(" 2. Pre-order traversal\n");
printf(" 3. In-order traversal\n");
printf(" 4. Post-order traversal\n");
printf(" 5. Delete node\n");
printf(" 6. Total nodes\n");
printf(" 7. Total external nodes \n");
printf(" 8. Total internal nodes \n");
printf(" 9. Find height \n");
printf("10. Smallest node \n");
printf("11. Largest node \n");
printf("12. Exit\n\n");
printf("Enter your choice (1-12): ");
scanf("%d",&choice);
clrscr();
switch(choice)
{
case 1:
printf("\nElement to be inserted into tree: ");
scanf("%d", &element);
insertElementIterative(&root, element);
break;
case 2:
printf("\nPre-order traversal of BST is \n");
preorderTraversalRecursive(root);
printf("\n\nPress any key to continue...");
getch();
break;
case 3:
printf("\nIn-order traversal of BST is \n");
inorderTraversalRecursive(root);
printf("\n\nPress any key to continue...");
getch();
break;
case 4:
printf("\nPost-order traversal of BST is \n");
postorderTraversalRecursive(root);
printf("\n\nPress any key to continue...");
getch();
break;
Page 40
www.magix.in
case 5:
printf("\nElement to delete from BST is: \n");
scanf("%d", &element);
deleteNode(&root, element);
break;
case 6:
printf("\nNumber of nodes in BST is %d", TotalNodes(root));
printf("\n\nPress any key to continue...");
getch();
break;
case 7:
printf("\nNumber of leaf nodes in BST is %d", externalNodes(root));
printf("\n\nPress any key to continue...");
getch();
break;
case 8:
printf("\nNumber of non-leaf nodes in BST is %d", internalNodes(root));
printf("\n\nPress any key to continue...");
getch();
break;
case 9:
printf("\nHeight of BST is %d", determineHeight(root));
printf("\n\nPress any key to continue...");
getch();
break;
case 10:
loc = findSmallestElement(root);
printf("\nSmallest node in BST is %d", loc->item);
printf("\n\nPress any key to continue...");
getch();
break;
case 11:
loc = findLargestElement(root);
printf("\nLargest node in BST is %d", loc->item);
printf("\n\nPress any key to continue...");
getch();
break;
case 12:
removeTreeFromMemory(&root);
exit(1);
}
}
}
Page 41
www.magix.in
M7.8: Balanced Binary Trees:
Efficiency of many important operations on trees is related to the Height of the tree –
for example searching, inserting, and deleting in a BST are all O(Height). In general,
the relation between Height (h) and the number of nodes (n) in a tree can vary from
h=n (degenerate tree) to h = log2 n. One way to improve efficiency is to force trees to
be height-balanced. A tree is perfectly height-balanced if the left and right subtrees of
any node are the same height as shown in following figure:
(Perfectly height balanced tree)
It is clear that every level there are twice as many nodes as at the previous level, so
we do indeed get h= O(log2 n). However, perfect height balance is very rare; it is only
possible if there are exactly 2h-1 nodes. Balanced binary trees are classified into two
categories:
Ø Height Balanced tree
Ø Weight Balanced tree
M7.8.1: Weight Balanced Binary Trees:
The nodes of a weight balanced tree contain a ‘data element’, a ‘left and right
pointer’, and a ‘probability or weight field’. The data element and left and right
pointers are essentially the same as any other node. The probability field is a special
addition for a weight balanced tree. This field holds the probability of the node being
accessed again. There are many different ways of coming up with this number. A
good example of such a metric is the computing the probability according to the
number of times the node has been previously searched for.
When the tree is set up, the nodes with the highest probability of access are placed
at the top. That way the nodes those are most likely to be accessed have the lowest
search time.
Page 42
www.magix.in
The tree is set up with the highest weighted node at the top of the tree or subtree.
The left subtree contain nodes whose data value are less than the current node, and
the right subtree contains nodes that have data values greater than the current data
value.
(A Weight Balanced Tree)
M7.8.2: Height Balanced Binary Trees/ AVL Trees:
A height balanced tree is also known as AVL trees after their Russian inventors
Adelson-Velskii and Landis.
A tree whose subtrees differ in height by no more than one and the subtrees are
height-balanced, too. An empty tree is height-balanced.
An AVL tree is a special type of binary tree that is always "partially" balanced in
height. In computer science, an AVL tree is a self-balancing binary search tree, and it
is the first such data structure to be invented.
Lookup, insertion, and deletion all take O(log2 n) time in both the average and worst
cases. Additions and deletions may require the tree to be rebalanced by one or more
tree rotations
The “balance factor” of a node is the height of its ‘left subtree’ minus the height of its
‘right subtree’. A node with balance factor 1, 0, or -1 is considered balanced. A node
with any other balance factor is considered unbalanced and requires rebalancing the
tree. The balance factor is either stored directly at each node or computed from the
heights of the subtrees.
Page 43
www.magix.in
If “T” is a nonempty binary tree with TL and TR as its left and right subtree, then T is an
AVL tree if and only if:
1. |hL – hR|<= 1 , where hL and hR are the heights of TL and TR, respectively,
2. and TL and TR are also AVL trees.
(Example of an AVL tree)
In an AVL tree the value for ‘bf’ (Balance Factor) will be chosen as:
-1
if hL < hR
0
if hL = hR
+1
if hL > hR
bf =
If the balance factor for any node in the tree is not in between these given domain
values (+1, 0, -1) then the tree is not considered as AVL tree.
Insertion in AVL Tree:
The INSERTION strategy is this:
1. Add the new value in the tree where it belongs (normal BST insertion).
2. Check if all subtrees are still height-balanced. If they are not, re-balance the
tree by changing its shape (i.e. moving around nodes or even whole
subtrees).
Let's look at a simple example. Suppose we start with the empty tree.
Page 44
www.magix.in
Insert 3:
Insert 6:
Insert 2:
So far things have been easy! Insert 1:
Insert 0:
The subtrees under ‘2’ are not height balanced. Compute the balance at each node
to see this. This is the deepest `unbalanced' node. Fix it.
When we have an imbalance, one of the subtrees is ‘tall’ or long the other subtree is
short. To re-balance, we need to shorten the tall side and/or lengthen the short side.
This can be done by what is called a rotation. In our example, ‘1’ rotates up into ‘2’s
position, ‘2’ goes down on the opposite side:
Page 45
www.magix.in
Now the left side is 1 shorter and the right side is 1 taller. This re-balanced subtree is
joined back to its place in the main tree.
Continuing on, suppose we now insert -1.
Computing the balance at each node, we see that everything is balanced except the
top node... so we rotate the tall subtree up and the root down in the opposite
direction.
Page 46
www.magix.in
Rotation is the operation that is used to restore balance in an AVL tree. For
INSERTION, it can be shown that you never need to do more than two rotations (one
rotation is not always enough) to restore balance, no matter how large the tree is. For
DELETE, rotation is also used to restore balance, but in this case there are
circumstances in which fixing the balance in one part of the tree creates an
imbalance higher up in the tree. So, in the worst case, you might have to do O(height)
rotations during a single DELETE operation.
M7.9: Threaded Binary Trees:
First let us see, what are the disadvantages of binary trees:
Ø In a binary tree, more than 50% of link fields have NULL values and more
memory space is wasted by storing NULL values.
Ø Traversing a tree with binary tree is time consuming. This is because, the
traversal of a tree either uses implicit stack (in case of recursive programs) or
explicit stack (in case of iterative programs). Whatever it is, stack is must. Most
of the time is spent in pushing and popping activities during traversing.
Ø Computations of predecessor and successor of given nodes is time consuming.
Ø In binary trees, only downward movement is possible.
All these disadvantages can be overcome using threaded binary tree.
In a binary tree, more than 50% of link fields have NULL values and more space is
wasted by the presence of NULL values. These link fields which contain NULL
character can be replaced by address of some nodes in the tree which facilitates
upward movement in the tree. These extra links which contains addresses of some
nodes (pointers) are called ‘threads’ and the tree is termed as threaded binary tree.
In general, a threaded binary tree is a binary tree which contains threads (i.e.,
address of some nodes) which facilitates upward movement in the tree.
The threads in a binary tree must be distinguished from normal pointers. In the
graphical representation of a threaded binary tree, the threads are shown by dotted
lines. In computer memory, an extra field, called ‘tag’ or ‘flag’ is used to distinguish a
thread from a normal pointer.
There are three types of threaded binary trees 1. In-threaded binary tress - In a binary tree, if LLink of any node contains NULL
and if it is replaced by address of inorder predecessor, then the resulting tree is
called “left inthreaded binary tree”. If Rlink of a node is null and if it is replaced
by address of in-order sucessor, the resulting tree is called “Right in-threaded
tree”. A “in-threaded binary tree” is one which is “both left and right inthreaded”.
Page 47
www.magix.in
2. Post-threaded binary trees - In a binary tree, if LLink of any node contains NULL
and if it is replaced by address of postorder predecessor, then the resulting tree
is called “left post threaded binary tree”. If “Rlink” of a node is NULL and if it is
replaced by address of post order sucessor, the resulting tree is called “right
post threaded tree”. A “post-threaded binary” tree is one which is both “left and
right post-threaded”.
3. Pre-threaded binary trees – In a binary tree, if Llink of any node contains NULL
and if it is replaced by address of preorder predecessor, then the resulting tree
is called “left pre threaded binary tree”. If Rlink of a node is null and if it is
replaced by address of preorder sucessor, the resulting tree is called “Rightprethreaded tree”. A “Prethreaded binary tree” is one which is “both left and
right pre threaded”.
(An example of In-threaded Binary tree)
This In-threaded binary tree is based on the in-order traversal of tree as:
A
B
C
D
E
F
G
H
I
Advantages of threaded binary trees –
Ø In a binary tree, more than 50% of space is wasted in storing null values. This
wastage of memory space is avoided by storing addresses of some nodes.
Ø Traversing of a threaded binary tree is very fast. This is because, it does not use
implicit or explicit stack.
Page 48
www.magix.in
Ø Computations of predecessor and successor of given nodes is very easy and
efficient.
Ø Any node can be accessed from any other node. Using threads, upward
movement is possible and using links downward movement is possible. Thus, in
a threaded binary tree, we can move in either direction.
Ø Even though insertion into a threaded binary tree and deletion from a threaded
binary tree are time consuming operations, they are very easy to implement.
Disadvantages of threaded binary trees –
Ø Here extra fields are required to check whether a link is a thread or not, and
occupies more memory when compared to un-threaded binary trees.
Ø Insertion and deletion of a node consumes more time than its counterpart, many
fields have to be modified.
M7.10: B- Trees: (Perfectly height balanced m-way search tree)
In computer science, a B-tree is a tree data structure that keeps data sorted and
allows searches, sequential access, insertions, and deletions in logarithmic time. Just
as AVL trees are balanced binary search trees, B-trees are balanced M-way search
trees. By imposing a balance condition, the shape of an AVL tree is constrained in a
way which guarantees that the search, insertion, and withdrawal operations are all
O(log2 n), where ‘n’ is the number of items in the tree. The shapes of B-Trees are
constrained for the same reasons and with the same effect.
A multi-way balanced tree is called as B-tree. Each node in a B-Tree contains more
than one key information in an order, either in ascending or descending.
B tree is not a binary tree. It grows from bottom to top rather than top to bottom.
Because of the multi-ways the B-tree is also called as m-way tree. Here ‘m’ specifies
the degree or order of the B-tree. In a B-tree of order ‘m’:
Ø Each node has maximum of m-1 keys.
Ø Each node has a maximum of ‘m’ links, means they can have maximum of ‘m’
children.
Ø Each node contains keys in order.
Ø All the leaves will be at the same level.
Ø If a node contains m-1 keys then it is said to be full. In a full node if key is added,
then the node will be split at median key value and the median will move to root
or as a value in root. So, the node is split into leaves and root.
Ø The insertion is always done at the leaves.
Ø The siblings share the weight means they can have equal number of keys or just
at the difference of 1.
Page 49
www.magix.in
Example of B-Tree:
Following is the simple example of a B-tree of order 4 with one node containing the
information 10, 15 and 20.
10
15
20
As the order is 4, the node has maximum 4-1=3 keys values and 4 links. Suppose
that a key 13 is to be inserted into the B-tree. As the node is full, the node will be
split at median 15 and a node with 15 becomes root. The B-tree after insertion of key
13 is:
15
10
13
20
Now suppose 9 is to be added to the B-tree. The key ‘9’ is compared with the root 15.
As ‘9’ is less than ‘15’, key ‘9’ is inserted in the left node of ‘15’, before ‘10’. The Btree after insertion is:
15
9
10
13
20
Now suppose 16 and 21 are to be added to the B-Tree, then they are added in the
right child of 15. The B-Tree becomes:
15
9
10
13
16
20
21
Now suppose that 8 is to be added to the B-tree. It is to be added at the left child of
15. But the node is full. So, the node will be split at median 10 and 10 will be moved
to root. The B-Tree after this split operation is:
10
8
Page 50
9
13
15
16 20
21
www.magix.in
The siblings of 15, left node has one key whereas right node has 3 keys. This is not
permitted in B-Tree. The siblings share the weight of the tree. So, the key 15 is
moved to the left node and the key 16 will be moved to the root. After these
operations the B-tree will be:
10
8
9
16
13 15
20
21
Similarly if 24 is to be added it can be added in the right node of 16. The B-tree after
this addition will be:
10
8
9
13
16
15
20
21 24
If the key 19 is to be added, it is supposed to be added to the right node of 16. As the
node will be full after addition, the node is split at median 21 and 21 is moved to the
root. So, the B-tree after this addition will be:
8
9
13
10
16 21
15
19
20
24
If the key 14 is to be added then it can be added in the left node of 16. The B-tree
after this addition will be:
10
8
9
13 14 15
16 21
19
20
24
Now suppose, if a key ‘12’ is to be added to the B-tree. It is supposed to be added at
the left node of ‘16’. It will be full after addition and requires a split. When the node
is split then median ‘14’ moves up to root. The root will be also full and needs split.
The root is split to have new root with the key ‘16’. The B-tree after this operation will
be:
Page 51
www.magix.in
16
10
8
9
14
12 13
21
15
19
20
24
In this way, the B-tree will grow from the leaves.
The best case height of a B-Tree is:
The worst case height of a B-Tree is:
where m is the maximum number of children a node can have.
M7.11: Heaps:
A heap is a binary tree that satisfies the following properties:
Ø Shape property
Ø Order property
By the ‘shape property’ we mean that heap must be a complete binary tree, whereas
by ‘order property’ we mean that for every node in the heap, the value stored in that
node is greater than or equal to the value in each of its children.
A heap that satisfies these properties is known as ‘max heap’.
However, if the order property is such that for every node in the heap, the value
stored in that node is less than or equal to the value in each of its children, that heap
is known as ‘min heap’. Example of MAX HEAP:
Page 52
www.magix.in
(Example of MIN HEAP)
Application of heaps:
Ø Sorting an array using efficient technique known as ‘heapsort’.
Ø Implementing a priority queue.
M7.11: Applications of Binary Trees:
Some applications of binary trees are discussed follows:
M7.11.1: Expression Trees: (Conversion of infix expression to prefix and postfix)
The compiler uses a binary tree to represent an arithmetic expression. A binary tree
can be constructed for an infix expression. When such tree is traversed using postorder it results to postfix expression. When it is traversed using pre-order traversal it
results to prefix expression.
These formats specify the position of a binary operator and its operands. In postfix
notation, the binary operator comes after its operands, and in infix notation, the
operator appears between its operands. A third notation, called ‘prefix notation,
places a binary operator before its operands. The expressions in table 7.1 include
each of its formats.
Page 53
www.magix.in
In an expression tree, each operator is an interior node whose children are operands
or subexpressions. Operands are in leaf node. Assume an arithmetic expression
involves the binary operators addition (+), subtraction (-), multiplication(*) and
division(/). In the expression tree, each operator has two children that are either
operands or subexpressions. A binary expression tree consists of:
Ø Leaf node which contain a single operand.
Ø Nonleaf node which contain a binary operator.
Ø The left and right subtrees of an operator, describing a subexpression,
which is evaluated and used as one of the operands for the operator.
The trees in following figure describe the expressions in table 7.1:
(Binary Expression Trees)
The preorder and postorder traversal of a binary expression tree produce the prefix
and postfix notation for the expression. An inorder traversal generates the infix form
of the expression, assuming that parentheses are not needed to determine the order
of evaluation. For instance, in above figure (c), the following are different traversals
of the expression a+b*c/d-e.
Preorder (prefix):
-+a/*bcde
Inorder (infix)
a+b*c/d–e
:
Postorder (postfix) :
Page 54
abc*d/+e www.magix.in
M7.11.2: Sorting:
When the binary search tree is traversed using inorder traversal technique the list
can be sorted in ascending order. This is a very good application of binary tree,
especially binary search tree. Let us understand with the help of following example:
Sort the following list of names of the days with the help of Binary search tree
(Assuming that the week starts with Monday (Mon) ) :
Tue, Thu, Sat, Fri, Sun, Mon, Wed
We can draw the binary search tree from the above list assuming that the week
starts with ‘Mon’. When we traverse the BST in in-order traversal, we get the sorted
list:
Page 55
www.magix.in
Now if we traverse the tree using ‘in-order’ traversal technique, we get the sorted list.
In ‘in-order’ traversal technique the nodes are visited in the order Left, Root, Right.
We start from the root, “Tue”. As it is not equal to NULL, we move to left. Left of node
‘Mon’ is NULL, so ‘Mon’ is processed to print out. As the right of ‘Mon’ is NULL, the
information of node “Tue” is printed out. Now the Right of ‘Tue’ is processed. In the
same way complete tree is traversed to get sorted list as follows:
Mon, Tue, Wed, Thu, Fri, Sat, Sun
M7.11.3: Heap Sorting:
A complete binary tree is a special case of a binary tree, in which all the levels,
except perhaps the last, are full; while on the last level, any missing nodes are to the
right of all the nodes that are present. For example, we could have:
(Example of complete binary tree)
In a complete binary tree if every node value is greater than its left and right node
values then such a complete binary tree is called as heap tree or just heap. If the
node value is greater than it is called as MAX heap. In a heap the node value may be
smaller than the children. If so then the heap becomes MIN heap. Such heaps can be
represented very easily in memory using one dimensional array. Heaps are useful in
sorting. Let us sort the following list of numbers using heap sort after constructing
the heap.
42, 53, 10, 40, 92, 16, 4, 65
Initially the heap is empty. The information 42 is stored in the root of the heap:
The next number 53 is inserted at the left of the node 42, to make complete binary tree.
Page 56
www.magix.in
The above binary tree is complete but it is not heap. We apply the process of
exchanging the root with child. So, the heap will be:
The next number 10 is inserted at the right of the root node 53. After insertion the
binary tree is:
The binary tree is complete and heap. The next number 40 is inserted into the heap
as left node of node 42 in the above heap. The binary tree is:
The binary tree is complete and heap. The next number 92 is inserted into the heap
as right node of node 42 in the above heap. The binary tree is:
The binary tree is complete but not heap. To make it heap, 92 is first exchanged with
42, then with 53. So, 92 becomes root of the heap. After exchanges the heap will be:
Page 57
www.magix.in
The next number 16 is inserted as left node of node 10. The binary tree is complete
but not heap. So, it is heapified by exchanging 16 with its root 10. Both the trees are
as follows:
The next number 4 is inserted as right node of node 16. The tree is as follows and it
is heap.
The next number 65 is inserted as left node 40 in the above heap. The tree is:
Page 58
www.magix.in
The binary tree is complete but not heap. To make it heap, 65 is first exchanged with
40, then with 53. So, 65 becomes left child of root and root of the children 53 and
42. The heap obtained after these exchanges will be the final heap because the list is
complete. The final heap is:
The process of creating heap is over. Now to sort the numbers we require an array of
size 8. The heap always contains the largest element as the root. So, to sort the
numbers the root of the heap is always deleted and added to the respective position
in the array from the last position. After the deletion of root from the heap, the heap
is adjusted to make it complete binary tree as well as heap. Step by step the
procedure is explained below:
The root 92 is deleted from the heap and added to the array at 8th position. The array
will be:
To obtain the heap after deletion of root 92, one of its children that is largest is
moved up as root. In this case 65 becomes root of the heap. Node 53 takes place of
node 65 and node 40 takes the place of node 53. The heap obtained after these
operations is:
Page 59
www.magix.in
The root 65 is deleted from the heap and added to the array at 7th position. The array
will be:
To obtain the heap after deletion of root 65, one of its children that is largest is
moved up as root. In this case 53 becomes root of the heap. So, node 53 takes the
place of node 65 and node 42 takes place of node 53. The tree obtained after these
operations is:
The above binary tree is not complete binary tree so it is not heap. To make the
binary tree complete, the last node 4 is placed as the right node of node 42. The tree
becomes complete and it is heap. So, the heap is:
The root 53 is deleted from the heap and added to the array at 6th position. The array
will be:
Page 60
www.magix.in
To obtain the heap after deletion of root 53, one of its children that is largest is
moved up as root. In this case 42 becomes root of the heap. So, node 42 takes the
place of node 53. One of the children of node 42, the one which is largest will
become the root of that sub tree. So, node 40 takes the place of node 42. The tree
obtained after these operations is:
The above binary tree is not complete binary tree so it is not heap. To make it
complete the last node 10 is placed as the left node of node 40. The tree becomes
complete and it is heap. So, the heap is:
The root 42 is deleted from the heap and added to the array at 5th position. The array
will be:
To obtain the heap after deletion of root 42, one of its children that is largest is
moved up as root. In this case 40 becomes root of the heap. So, node 40 takes the
place of node 42. Node 10 takes the place of node 40. The tree obtained after these
operation is:
Page 61
www.magix.in
The binary tree obtained is not complete binary tree so it is not heap. To make the
binary tree complete the last node 4 is placed as the left node of node 10. The tree
becomes complete and it is heap. So, the heap is:
The root 40 is deleted from the heap and added to the array at 4th position. The array
will be:
To obtain the heap after deletion of root 40, one of its children that is largest is
moved up as root. In this case 16 becomes root of the heap. So, node 16 takes the
place of node 40. The node 4 takes the place of node 16, to make the binary tree as
heap. The tree obtained after these operations is:
The above binary tree is complete and it is also heap. The root 16 is deleted from the
heap and added to the array at 3rd position. The array will be:
To obtain the heap after deletion of root 16, one of its children that is largest is
moved up as root. In this case 10 becomes root of the heap. So, node 10 takes the
place of node 16. Similarly node 4 takes the place of node 10. After the operations
the heap will be:
Page 62
www.magix.in
The root 10 is deleted from the heap and added to the array at 2nd position. The array
will be:
After the operation node 4 will move up and takes the place of 10. The heap contains
only node 4. It is deleted and added to the array at 1st position. The sorted array will
be:
Page 63
www.magix.in