09 DS Tree 2024
09 DS Tree 2024
And
Its Applications
n Selecting one data structure type over the other should be done
carefully by considering the relationship among the data elements
that needs to be stored.
A Specific Example
n Also it does not tell which managers are responsible for which
workers and so on.
n Applications:
n Organization Charts
n File Systems
n Programming Environment
Tree Definition
n The node r is called the root of the tree T, and the elements of the
set S are called its subtrees.
n n1, n2, n6 is a path of length 2 from the root n1 to the node n6.
Height and Depth
n The depth, or level, of a node n is the length of the path from the
root to n.
Example
A Level 0
Level 1
B C
D E Level 2
Depth is 3. F G Level 3
Tree Properties
A Property Value
Number of nodes 9
Height 4
B C
Root Node A
Leaves C, D, F, H, I
D E F Interior nodes B, E, G
Ancestors of H A, B, E, G
Descendants of B D, E, F, G, H, I
Siblings of E D, F
G Right subtree of A tree at C
H I
Other Terms
n The size of a tree is the number of nodes it contains.
n The level order traversal algorithm visits the root, then visits
each element on the first level, then visits each element on the
second level, and so forth, each time visiting all the elements on
one level before going down to the next level.
n If the tree is drawn in the usual manner with its root at the top
and leaves near the bottom, then the level order pattern is the
same as left-to-right top-to-bottom pattern.
Level Order Example
Level order Traversal - Algorithm
• The preorder traversal of the tree shown above would visit the
nodes in this order: a, b, e, h, i, f, c, d, g, j, k, l, m.
• Note that the preorder traversal of a tree can be obtained by
traversing the tree, beginning at the root and visiting each node the
first time it is encountered on the left.
Preorder Traversal - Algorithm
n A binary tree is either the empty set or a triple T = (r, TL, TR),
where r is a node and TL and TR are disjoint binary trees, neither
of which contains r.
n The node r is called the root of the tree T, and the subtrees TL and
TR are called the left subtree and the right subtree of T rooted at r.
Binary Tree
n A binary tree is a tree in which no node can have more than two
subtrees. In other words, a node can have zero, one or two subtrees.
Five binary trees with three nodes
A
B C
D E
F G
Complete Binary Treetrees)
Complete Binary Tree: A binary tree T in which all levels are fully
filled, except for possibly the last level, which is filled from left to
right.
It’s useful for improving storage optimization because it ensures
that each level is filled entirely before populating the next.
1 1
1 13
1 2 3
2 2 2 3 1
1 4 5 6
4 2 3
2 3
4 5
4 56 7
Complete Binary Tree
Make a Note
n Complete binary trees are important because they have a simple
and natural implementation using ordinary arrays.
n Figure above shows the incomplete binary tree and the natural mapping
of its nodes into an array which leaves some gaps.
Illustration of Array Representation
15
8 20
2 11 30 27
6 18 12
13
15 8 20 2 11 30 27 13 6 18 12
0 1 2 3 4 5 6 7 8 9 10
n Notice: Left child of t[4] (of data 11) is t[2*4+1]=T[9] (of data 18), and
its right child is t[2*4+2]=T[10] (of data 12).
n Disadvantages
n Wastage of memory
n Insertion and Deletion will be costlier
n Array size and depth
Linked List Representation of Binary
Tree
n The most popular and practical way of representing a binary tree is
using linked list (or pointers). In linked list, every element is represented
as nodes. A node consists of three fields such as :
n (a) Left Child (LChild)
n (b) Information of the Node (Info)
n (c) Right Child (RChild)
n The LChild links points to the left child of the node, Info holds the
information of the node and the RChild holds the address of right child
node of the node. The structure of a binary tree node is shown below:
Binary Tree Representations (Linked
List)
n The Binary Tree ADT extends the Tree ADT, i.e., it inherits all the
methods of the Tree ADT, in addition to that it supports the
following additional accessor methods:
n position left(p): return the left child of p, an error condition
occurs if p has no left child.
n position right(p): return the right child of p, an error condition
occurs if p has no right child.
n boolean hasLeft(p): test whether p has a left child
n boolean hasRight(p): test whether p has a right child
Linked List Implementation
n Advantages
n No wastage of memory
n Insertion and Deletion will be easy
n Disadvantages
n Does not provide direct access
n Additional space in each node.
Binary Tree Traversal
n The three traversal algorithms that are used for general trees
apply to binary trees as well: the preorder traversal, the
postorder traversal, and the level order traversal.
1. Initialize a queue.
2. Enqueue the root.
3. Repeat steps 4–7 until the queue is empty.
4. Dequeue a node x from the queue.
5. Visit x.
6. Enqueue the left child of x if it exists.
7. Enqueue the right child of x if it exists.
Level Order
Preorder Traversal
Postorder Traversal:
1. Traverse left subtree
2. Traverse right subtree
3. Visit the root
Illustrations for Traversals
n Preorder: 1 3 5 4 6 7 8 9 10 11 12
5 8 9
n Inorder: 4 5 6 3 1 8 7 9 11 10 12
Postorder: 4 6 5 3 8 11 12 10 9 7 1 4 10
n 6
11 12
Illustrations for Traversals (Contd.)
15
8 20
2 11 27
6 10 12 22 30
3 7 14
Illustrations for Traversals (Contd.)
6 10 12 22 30
3 7 14
Code for the Traversal Techniques
void preOrder(Tree *root){
if (root == NULL) return;
visit(root->info);
n The code for visit depends on
preOrder(root->left);
the application
preOrder(root-> right);
n A typical example for visit(…) is }
to print out the data part of its void inOrder(Tree *root){
input node if (root == NULL) return;
inOrder(root-> left);
visit(root->info);
typedef struct node { inOrder(root-> right);
int info; }
struct node *left; void postOrder(Tree *root){
struct node *right; if (root == NULL) return;
} Tree; postOrder(root-> left);
postOrder(root->right));
visit(root->info);
}
A
B C Code for the Traversal Techniques
void preOrder(Tree *root) {
void preOrder(Tree *root) {
if (root == NULL) return;
if (root == NULL) return;
visit(root->info);
visit(root->info);
preOrder(root->left);
preOrder(root->left);
preOrder(root-> right);
preOrder(root-> right);
}
}
void preOrder(Tree *root) {
void preOrder(Tree *root) {
if (root == NULL) return;
if (root == NULL) return;
visit(root->info);
visit(root->info);
preOrder(root->left);
preOrder(root->left);
preOrder(root-> right);
preOrder(root-> right);
}
}
void preOrder(Tree *root) {
void preOrder(Tree *root) {
if (root == NULL) return;
if (root == NULL) return;
visit(root->info);
visit(root->info);
preOrder(root->left);
preOrder(root->left);
preOrder(root-> right);
preOrder(root-> right);
}
}
void preOrder(Tree *root) {
void preOrder(Tree *root) {
if (root == NULL) return;
if (root == NULL) return;
visit(root->info);
visit(root->info);
preOrder(root->left);
preOrder(root->left);
preOrder(root-> right);
preOrder(root-> right);
}
}
A
B C Code for the Traversal Techniques
void inOrder(Tree *root) {
void inOrder(Tree *root) {
if (root == NULL) return;
if (root == NULL) return;
inOrder(root->left);
inOrder(root->left);
visit(root->info);
visit(root->info);
inOrder(root-> right);
inOrder(root-> right);
}
}
void inOrder(Tree *root) {
void inOrder(Tree *root) {
if (root == NULL) return;
if (root == NULL) return;
inOrder(root->left);
inOrder(root->left);
visit(root->info);
visit(root->info);
inOrder(root-> right);
inOrder(root-> right);
}
}
void inOrder(Tree *root) {
void inOrder(Tree *root) {
if (root == NULL) return;
if (root == NULL) return;
inOrder(root->left);
inOrder(root->left);
visit(root->info);
visit(root->info);
inOrder(root-> right);
inOrder(root-> right);
}
}
void inOrder(Tree *root) {
void inOrder(Tree *root) {
if (root == NULL) return;
if (root == NULL) return;
inOrder(root->left);
inOrder(root->left);
visit(root->info);
visit(root->info);
inOrder(root-> right);
inOrder(root-> right);
}
}
A
B C Code for the Traversal Techniques
void postOrder(Tree *root) {
void postOrder(Tree *root) { if (root == NULL) return;
if (root == NULL) return; postOrder(root->left);
postOrder(root->left); postOrder(root-> right);
postOrder(root-> right); visit(root->info);
visit(root->info); }
} void postOrder(Tree *root) {
void postOrder(Tree *root) { if (root == NULL) return;
if (root == NULL) return; postOrder(root->left);
postOrder(root->left); postOrder(root-> right);
postOrder(root-> right); visit(root->info);
visit(root->info); }
} void postOrder(Tree *root) {
void postOrder(Tree *root) { if (root == NULL) return;
if (root == NULL) return; postOrder(root->left);
postOrder(root->left); postOrder(root-> right);
postOrder(root-> right); visit(root->info);
visit(root->info); }
} void postOrder(Tree *root) {
void postOrder(Tree *root) { if (root == NULL) return;
if (root == NULL) return; postOrder(root->left);
postOrder(root->left); postOrder(root-> right);
postOrder(root-> right); visit(root->info);
visit(root->info); }
}
Nonrecursive Preorder Traversal:
General Algorithm
a a
preorder = ab
b b
inorder = ab b a
a b
postorder = ab b b
a a
Binary Tree Construction
preorder = ab a a
postorder = ba b b
preorder = abc a a
postorder = bca b b c
c
If the tree is full the Preorder and postorder uniquely define a binary tree.
Preorder And Postorder
preorder = 1, 2, 4, 8, 9, 5, 3, 6, 7
postorder = 8, 9, 4, 5, 2, 6, 7, 3, 1
preorder = 1, 2, 4, 8, 9, 5, 3, 6, 7
postorder = 8, 9, 4, 5, 2, 6, 7, 3, 1
1 1
/ \ / \
/ \ 2 3
{8, 9, 4, 5, 2} {6, 7, 3} / \ / \
4 5 6 7
/\
8 9
Inorder And Preorder
n inorder: g d h b e i a f j c
n preorder: a b d g h e i c f j
n Scan the preorder left to right using the inorder to separate left
and right subtrees.
n a is the root of the tree: gdhbei are nodes in the left subtree: fjc
are nodes in the right subtree.
gdhbei fjc
Inorder And Preorder
gdhbei fjc
n preorder: b d g h e i c f j
n b is the next root; gdh are in the left subtree; ei are in the right subtree.
a
b fjc
gdh ei
Inorder And Preorder
b fjc n preorder: d g h e i c f j
gdh ei n d is the next root; g is in the left
subtree; h is in the right subtree.
a
b fjc
d ei
g h
Inorder And Postorder
n inorder: g d h b e i a f j c
n postorder: g h d i e b j f c a
struct node {
int info;
struct node* left;
struct node* right;
};
12
/ \
20 30
/ \
10 40
MCQ-2
Suppose the level of root is 1 and levels of left and right children of root is 2.
The maximum number of nodes on level i of a binary tree is
(A) 2i-1
(B) 2i
(C) 2i+1
(D) 2(i+1)/2
(E) None of the above
MCQ-2
Suppose the level of root is 1 and levels of left and right children of root is 2.
The maximum number of nodes on level i of a binary tree is
(A) 2i-1
(B) 2i
(C) 2i+1
(D) 2(i+1)/2
(E) None of the above
Answer: (A)
Explanation: Number of nodes of binary tree will be maximum only when tree
is full complete, therefore answer is 2i-1
So, option (A) is true.
MCQ-3
In a complete k-ary tree, every internal node has exactly k children or no child.
What is the number of leaf nodes in such a tree with n internal nodes?
(A) nk
(B) (n – 1) k+ 1
(C) n( k – 1) + 1
(D) n(k – 1)
(E) None of the above
where L is the number of leaf nodes
MCQ-3 and n is the number of internal nodes.
since it is a complete k tree, so every
internal node will have k children.
In a complete k-ary tree, every internal Total children = n*k
node has exactly k children or no child. Total nodes = n*k + 1
What is the number of leaf nodes in such
Leaf nodes = n*k+1-n = (k-1)*n+1
a tree with n internal nodes?
Example:
(A) nk
o
(B) (n – 1) k+ 1
/ | \
(C) n(k – 1) + 1
o o o
(D) n(k – 1)
/|\ /|\ /|\
(E) None of the above
o o oo o oo oo
Answer: (C)
k=3
Explanation: For an k-ary tree where each
node has k children or no child, following Number of internal nodes n = 4
relation holds Number of leaf nodes = (k-1)*n + 1
L = (k-1)*n + 1 = (3-1)*4 + 1 = 9
MCQ-4
The maximum number of binary trees that can be formed with three unlabeled
nodes is:
(A) 1
(B) 5
(C) 4
(D) 3
(E) None of the above
Note that nodes are
unlabeled. If the nodes
MCQ-4 are labeled, we get
more number of trees.
We can find the
The maximum number of binary
O O number of binary tree
trees that can be formed with
/ \ by Catalan number
three unlabeled nodes is:
number:
(A) 1 O O
Here n = 3
(B) 5 / \
Number of binary tree
(C) 4 O O
= (2nCn)/ (n+1)
(D) 3 (ii) (iv)
= (2*3C3)/ (3+1)
(E) None of the above = 5.
Answer: (B) O O
So, option (B) is
Explanation: Following are all / \ correct.
possible unlabeled binary tree O O The first few Catalan
O \ / numbers for n = 0, 1,
/ \ O O 2, 3, … are 1, 1, 2, 5,
O O (iii) (v) 14, 42, 132, 429, 1430,
4862, …
(i)
MCQ-5
The number of leaf nodes in a rooted tree of n nodes, with each node having 0
or 3 children is:
(A) n/2
(B) (n-1)/3
(C) (n-1)/2
(D) (2n+1)/3
(E) None of the above
MCQ-5
What is the number of leaf nodes in a rooted tree of n nodes, with each node
having 0 or 3 children?
(A) n/2
(B) (n-1)/3
(C) (n-1)/2
(D) (2n+1)/3
(E) None of the above
Answer: (D)
Explanation: Let L be the number of leaf nodes and I be the number of internal
nodes, then following relation holds for above given tree
L = (3-1)I + 1 = 2I + 1
Total number of nodes(n) is sum of leaf nodes and internal nodes
n = L + I => I = n - L Putting the value of I in the above equation
We get L = (2n+1)/3
MCQ-6
A complete n-ary tree is a tree in which each node has n children or no
children. Let I be the number of internal nodes and L be the number of leaves
in a complete n-ary tree. If L = 41, and I = 10, what is the value of n?
(A) 6
(B) 3
(C) 4
(D) 5
(E) None of the above
MCQ-6
A complete n-ary tree is a tree in which Explanation: For an n-ary tree where
each node has n children or no children. each node has n children or no children,
Let I be the number of internal nodes and following relation holds
L be the number of leaves in a complete L = (n-1)*I + 1
n-ary tree. If L = 41, and I = 10, what is
Where L is the number of leaf nodes and
the value of n?
I is the number of internal nodes.
(A) 6
(B) 3
Let us find out the value of n for the
(C) 4 given data.
(D) 5
(E) None of the above L = 41 , I = 10
41 = 10*(n-1) + 1
Answer: (D) (n-1) = 4
n=5
MCQ-7
A scheme for storing binary trees in an array X is as follows. Indexing of X
starts at 1 instead of 0. the root is stored at X[1]. For a node stored at X[i], the
left child, if any, is stored in X[2i] and the right child, if any, in X[2i+1]. To be
able to store any binary tree on n nodes the minimum size of X should be.
(A) log2n
(B) n
(C) 2n + 1
(D) 2^n — 1
(E) None of the above
MCQ-7
A scheme for storing binary trees in an Explanation: For a right skewed binary
array X is as follows. Indexing of X tree, number of nodes will be 2n – 1. For
starts at 1 instead of 0. the root is example, in below binary tree, node ‘A’
stored at X[1]. For a node stored at X[i], will be stored at index 1, ‘B’ at index 3,
the left child, if any, is stored in X[2i] ‘C’ at index 7 and ‘D’ at index 15.
and the right child, if any, in X[2i+1].
To be able to store any binary tree on n A
nodes the minimum size of X should be. \
\
(A) log2n B
(B) n \
(C) 2n + 1 \
(D) 2n - 1 C
(E) None of the above \
\
Answer: (D) D
MCQ-8
Consider the following nested representation of binary trees: (X Y Z) indicates Y
and Z are the left and right sub stress, respectively, of node X. Note that Y and Z
may be NULL, or further nested. Which of the following represents a valid binary
tree?
(A) (1 2 (4 5 6 7))
(B) (1 (2 3 4) 5 6) 7)
(C) (1 (2 3 4)(5 6 7))
(D) (1 (2 3 NULL) (4 5))
(E) None of the above
MCQ-8
Explanation: C is fine.
Consider the following nested
representation of binary trees: (X Y Z) (1 (2 3 4)(5 6 7)) represents following
indicates Y and Z are the left and right binary tree
sub stress, respectively, of node X.
Note that Y and Z may be NULL, or 1
further nested. Which of the following / \
represents a valid binary tree?
2 5
(A) (1 2 (4 5 6 7))
/\ /\
(B) (1 (2 3 4) 5 6) 7)
3 4 6 7
(C) (1 (2 3 4)(5 6 7))
A) (1 2 (4 5 6 7)) is not fine as there are 4
(D) (1 (2 3 NULL) (4 5)) elements in one bracket.
(E) None of the above B) (1 (2 3 4) 5 6) 7) is not fine as there are
2 opening brackets and 3 closing.
Answer: (C) D) (1 (2 3 NULL) (4 5)) is not fine one
bracket has only two entries (4 5)
MCQ-9
Consider a node X in a Binary Tree. Given that X has two children, let Y be
Inorder successor of X. Which of the following is true about Y?
(A) Y has no right child
(B) Y has no left child
(C) Y has both children
(D) None of the above
(E) None of the above
MCQ-9
Consider a node X in a Binary Tree. Given that X has two children, let Y be
Inorder successor of X. Which of the following is true about Y?
(A) Y has no right child
(B) Y has no left child
(C) Y has both children
(D) None of the above
(E) None of the above
Answer: (B)
Answer: (A)
Explanation:
Number of nodes is maximum for a perfect binary tree.
A perfect binary tree of height h has 2h+1 - 1 nodes
- /
8 5 + 3
4 2
Levels Indicate Precedence
§ The levels of the nodes in the tree indicate their relative precedence
of evaluation (Do not need parentheses to indicate precedence).
§ Operations at deeper levels of the tree are evaluated first than those
upper.
+ 3
4 2
( 4 + 2 ) * 3 = 18
Expression Tree Examples
+
3 -
3+4*5-9+6 3+(4*5-(9+6))
* +
4 5 9 6
log
log x log(x)
x
!
n! n!
n
Why Expression trees?
evalExpr(ExpressionTree t){
if(t->left == NULL && t->right == NULL) // node t is a leaf node
return (t->info) // which is an operand
else {
op = t->info
opnd1 = evalExpr(t->left)
opnd2 = evalExpr(t->right) ;
return(eval(opnd1, op, opnd2))
}
} +
2 * Order of evaluation: 3 1 2
(2 + ((5 – 1) * 3))
- 3
5 1
Evaluating an Expression tree
evalExpr(ExpressionTree t){
+
if(t->left==NULL && t->right==NULL)
2 * return (t->info)
else {
- 3
op = t->info
5 1 opnd1 = evalExpr(t->left)
evalExpr(ExpressionTree t){
opnd2 = evalExpr(t->right) ;
if(t->left==NULL && t->right==NULL)
return(eval(opnd1, op, opnd2)) }
return (t->info)
}
else {
op = t->info evalExpr(ExpressionTree t){
opnd1 = evalExpr(t->left) if(t->left==NULL && t->right==NULL)
opnd2 = evalExpr(t->right) ; return (t->info)
return(eval(opnd1, op, opnd2)) } else {
} op = t->info
opnd1 = evalExpr(t->left)
evalExpr(ExpressionTree t){ opnd2 = evalExpr(t->right) ;
if(t->left==NULL && t->right==NULL) return(eval(opnd1, op, opnd2)) }
return (t->info) }
else { ... }
evalExpr(ExpressionTree t){
}
if(t->left==NULL && t->right==NULL)
return (t->info)
else { ... }
}
Constructing an expression tree from a
postfix expression
n The pseudo code algorithm to convert a valid postfix expression,
containing binary operators, to an expression tree:
- /
8 5 + 3
4 2
Infix: ((8-5)*((4+2)/3))
Prefix: *-85 /+423
Postfix: 85- 42+3/*
Inorder Traversal: (A + H) / (M - Y)
Print second
tree
+ -
A H M Y
+ -
A H M Y
+ -
A H M Y
34 41 56 63 72 89 95
0 1 2 3 4 5 6
34 41 56 72 89 95
0 1 2 4 5 6
72 95
34 56
0 2 4 6
Organization Rule for BST
• values at all nodes in the left subtree of a node are less than
the node value
• values in all nodes at the right subtree of a node are greater
than the node values
63
41 89
34 56 72 95
Binary Tree
method insert(key)
n find the place for the new item near the frontier of the BST while
retaining its organization of data:
n starting at the root it probes down the tree till it finds a node whose left
or right pointer is NULL and that is a logical place for the new value to
be inserted
Operations:: Insertion
Case 1: The Tree is Empty
• Set the root to a new node containing the item
Case 2: The Tree is Not Empty
• Call a recursive function to insert the item
10
10 > 7
7
10 > 9
5 9
4 6 8 10
BST Insertion: Pseudocode
if tree is empty
create a root node with the new key
else
if key = node->info
// replace the node with the new value (unique node values)
else if key > node->info // compare key with the right subtree
if the right subtree is empty create a leaf node
add key in right subtree
else if key < node->info // compare key with the left subtree
if the left subtree is empty create a leaf node
add key to the left subtree
BST Insertion: Nonrecursive Code
void insert (treeNode root, int key) { treeNode findPos(treeNode root, int
treeNode newNode, parent; key) {
newNode=(treeNode) malloc(sizeof(struct node)); treeNode curr=root;
newNode->info = key; while (root != NULL) {
newNode->left = newNode->right = NULL; curr=root;
if(root==NULL) { if (key > root->info)
root = newNode; root=root->right;
else if (key < root->info)
return;
root=root->left;
}
else return root;
parent = findPos(root, key);
}
if(key<parent->info) return curr;
parent->left=newNode; }
else if (key>parent->info)
parent->right = newNode;
return;
}
BST Insertion: Nonrecursive Code
cursor
5 9
4 6 8 10
7
Removing 4
replace the link in the
parent with NULL 5 9
6 8 10
Removal in BST: Example
Case 2: removing a node with 2 subtrees
- replace the node's value with the max value in the left subtree
- delete the max node in the left subtree
What other element
can be used as
Removing 7 replacement?
cursor
cursor
7 6
5 9 5 9
4 6 8 10 4 8 10
Removal in BST: Example
Case 3: removing a node with 1 empty subtree
parent
parent
7 7
cursor
5 9 cursor 5 9
6 8 10 6 8 10
Removal in BST: Example
Removing 5
parent
parent
7 cursor 7
cursor
5 9 5 9
4 8 10 4 8 10
Removal in BST
BST *root;
BST *root;
for (int i = 1; i <= 8; i++)
insert(root, i);
BST *root;
for (int i = 1; i <= 8; i++)
insert(root, random());
(A) 9, 10, 15, 22, 23, 25, 27, 29, 40, 50, 60, 95
(B) 9, 10, 15, 22, 40, 50, 60, 95, 23, 25, 27, 29
(C) 29, 15, 9, 10, 25, 22, 23, 27, 40, 60, 50, 95
(D) 95, 50, 60, 40, 27, 23, 22, 25, 10, 9, 15, 29
MCQ-1
Answer: (A)
Explanation: Inorder traversal of a BST always gives elements in increasing
order. Among all four options, a) is the only increasing order sequence.
Better Search Trees
d log2N
Binary Search Tree - Worst Time
1 4
2
2 5
3
1 3
4
4
5 Is this “balanced”?
2 6
6
1 3 5 7 7
Motivation
3
5 13
8
5 20
13
18 3 8 18 22
20
22
Motivation
6 5
Insert 2 &
4 9 complete tree 2 8
1 5 8 1 4 6 9
AVL - Good but not Perfect Balance
height=2 BF=1-0=1 2
6 6
1 0 1 1
4 9 4 9
0 0 0 0 0
1 5 1 5 8
height of node = h
balance factor = hleft-hright
empty height = -1
Node Heights after Insert 7
0
7
height of node = h
balance factor = hleft-hright
empty height = -1
Insert and Rotation in AVL Trees
2 0
6 6
1 2 1 1
4 9 4 8
0 0 1 0 0 0 0
1 5 8 1 5 7 9
0
7
Insertions in AVL Trees
12
5 23
2 9 18 30
1 4 7 10
Generalizing the Example
12
5 23
2 9 18 30
1 4 7 10
Generalizing the example
12
X Y
Generalized Single Rotation
k2
k1
Y Z
Generalized Single Rotation
k2
k1
X Y
Single Rotations
Right Rotation
k2 Left Rotation k1
k1 k2
Z X
X Y Y Z
Single Rotations: LL
Inserting into subtree X
k2 destroys the AVL
property at node k2
k1
nnew
AVL Insertion: Single Rotation
k2
Do a “right rotation”
k1
h
Z
h+1 h
X
Single right rotation
k2 Do a “right rotation”
k1
h
Z
h+1 h
X
Single Rotation Completed
k1
k2
h+1
h h
X
Y Z
8 22
4 10 19 24
3 6 17 20
16
Single Rotations: RR
k2
k1
Y Z
nnew
Example: Single Rotation: RR
insert(26)
15 15
8 22 8 24
4 10 19 24 4 10 22 25
3 6 23 25 3 6 19 23
26
26
AVL Insertion: Double Rotation
Consider a valid k2
AVL subtree
k1
h
h h Z
X Y
AVL Insertion: Double Rotation
k1 h
Z
h h+1
Y
AVL Insertion: Inside Case
k1 “Right rotation”
does not restore
balance… now k1 is
out of balance
h k2
X h
h+1
Y
AVL Insertion: Double Rotation
k1 h
Z
h h+1
Y
AVL Insertion: Double Rotation
Y = node k3 and k2
subtrees V and W
k1 h
Z
h k3 h+1
X
h or h-1
V W
AVL Insertion: Double Rotation
k2 We will do a left-right
“double rotation” . . .
k1
Z
k3
V W
Double Rotation: First Rotation
k2 left rotation complete
k3
k1 Z
X V
Double rotation: Second Rotation
k2
Now do a right rotation
k3
k1 Z
X
V
Double Rotation: Second Rotation
right rotation complete
k1 k2
h h
h or h-1
X W Z
V
AVL Tree Example:
• Insert 14, 17, 11, 7, 53, 4, 13 into an empty AVL tree
14
11 17
7 53
4
AVL Tree Example:
• Insert 14, 17, 11, 7, 53, 4, 13 into an empty AVL tree
14
7 17
4 11 53
13
AVL Tree Example:
• Now insert 12
14
7 17
4 11 53
13
12
AVL Tree Example:
• Now insert 12
14
7 17
4 11 53
12
13
AVL Tree Example:
• Now the AVL tree is balanced.
14
7 17
4 12 53
11 13
AVL Tree Example:
• Now insert 8
14
7 17
4 12 53
11 13
8
AVL Tree Example:
• Now insert 8
14
7 17
4 11 53
8 12
13
AVL Tree Example:
• Now the AVL tree is balanced.
14
11 17
7 12 53
4 8 13
Delete: Single Rotation
• Consider deepest unbalanced node
– Case 1: Left child’s left side is too high
– Case 4: Right child’s right side is too high
h+2 – The parents may need to be recursively rotated
h+1
Height = h
h/h-1
h Delete Before Deletion
h+1/h+2
h/h+1
h+1
h-1 h
h/h-1 h/h-1 h-1
h
Height = h
14
11 17
7 12 53
4 8 13
AVL Tree Example
After removal of 53, tree is unbalanced
14
11 17
7 12
4 8 13
AVL Tree Example
Balanced! Then Remove 11
11
7 14
4 8 12 17
13
AVL Tree Example
After removal of 11, 8, which is the largest in its left branch is
replacing 11
11 8
7 14 7 14
4 8 12 17 4 12 17
13 13
AVL Tree Example
Remove 8, tree becomes unbalanced. Then 7, which is the largest
in its left branch is replacing 8
8 7
7 14 4 14
4 12 17 12 17
13
13
AVL Tree Example
So, Removal of 8 amkes tree unbalanced. So make it balanced,
rotation is required
4 12
14
13 17
AVL Tree Example
Balanced!!
12
7 14
4 13 17
C-code to Implement AVL Tree
int main() {
struct node *root = NULL;
root = insert(root, 10);
root = insert(root, 20);
root = insert(root, 30);
root = insert(root, 40);
root = insert(root, 50);
root = insert(root, 25);
printf("Pre order traversal of the constructed AVL tree is \n");
preOrder(root);
return 0;
}
Exercises
n Build an AVL tree with the following values:
15, 20, 24, 10, 13, 7, 30, 36, 25
15, 20, 24, 10, 13, 7, 30, 36, 25
20
15
15 24
20
10
24
13
20 20
13 24 15 24
10 15 13
10
15, 20, 24, 10, 13, 7, 30, 36, 25
20
13
13 24 10 20
10 15 7 15 24
7 30
13 36
10 20
7 15 30
24 36
15, 20, 24, 10, 13, 7, 30, 36, 25
13 13
10 20 10 20
7 15 30 7 15 24
24 36 30
25 13 25 36
10 24
7 20 30
15 25 36
Remove 24 and 20 from the AVL tree.
13 13
10 24 10 20
7 20 30 7 15 30
15 25 36 25 36
13 13
10 30 10 15
7 15 36 7 30
25 25 36
C-code to Implement AVL Tree
struct Node* deleteNode(struct Node* root, int key) {
int bf;
struct Node* temp;
if (root == NULL) return root;
if ( key < root->info)
root->left=deleteNode(root->left, key);
else if( key > root->info)
root->right=deleteNode(root->right, key);
else {
if((root->left==NULL)||(root->right==NULL)) {
temp=root->left?root->left:root->right;
if(temp == NULL) {
temp = root;
root = NULL;
}
else root->info=temp->info; (or *root = *temp)//Copy the content of temp to root
free(temp);
}
else {
temp=maxLSTree(root->left);
root->info=temp->info; // Copy the inorder predecessor's data to this node
root->left=deleteNode(root->left, temp->info); // Delete the inorder predecessor
}
}
C-code to Implement AVL Tree
if (root == NULL) return root;
root->ht=max(height(root->left), height(root->right))+1;
bf=getBalance(root);
if(bf > 1 && getBalance(root->left) >= 0)
return rightRotate(root);
if(bf > 1 && getBalance(root->left) < 0) {
root->left = leftRotate(root->left);
return rightRotate(root);
}
if(bf < -1 && getBalance(root->right) <= 0)
return leftRotate(root);
if(bf < -1 && getBalance(root->right) > 0) {
root->right = rightRotate(root->right);
return leftRotate(root);
}
return root;
}
struct node {
struct node *left;
boolean lthread;
int info;
boolean rthread;
struct node *right;
};
Threaded Tree Traversal Code
struct node *insert(struct node *root, int ikey) { if(ptr->rthread == false)
struct node *tmp, *par, *ptr; ptr = ptr->right;
int found=0; else
ptr = root; break;
par = NULL; }
while(ptr!=NULL) { }
if(ikey == ptr->info) { if(found)
found =1; printf("\nDuplicate key");
break; else {
} tmp=(struct node *)malloc(sizeof(struct
par = ptr; node));
if(ikey < ptr->info) { tmp->info=ikey;
if(ptr->lthread == false) tmp->lthread = true;
ptr = ptr->left; tmp->rthread = true;
else if(par==NULL) {
break; root=tmp;
} tmp->left=NULL;
else { tmp->right=NULL;
}
Threaded Tree Traversal Code
else if(ikey < par->info) {
tmp->left=par->left;
tmp->right=par;
par->lthread=false;
par->left=tmp;
}
else {
tmp->left=par;
tmp->right=par->right;
par->rthread=false;
par->right=tmp;
}
}
return root;
}
Threaded Tree Traversal Code
if(ptr->rthread == false)
ptr = ptr->right;
struct node *del(struct node *root, int dkey) {
else
struct node *par,*ptr;
break;
int found=0;
}
ptr = root;
}
par = NULL;
if(found==0)
while(ptr!=NULL) {
printf("\ndkey not present in tree");
if(dkey == ptr->info) {
else if(ptr->lthread==false && ptr-
found =1;
>rthread==false) /*2 children*/
break;
root = case_c(root, par, ptr);
}
else if(ptr->lthread==false) /*only left
par = ptr;
child*/
if(dkey < ptr->info) {
root = case_b(root, par, ptr);
if(ptr->lthread == false)
else if(ptr->rthread==false) /*only right
ptr = ptr->left;
child*/
else
root = case_b(root, par, ptr);
break;
else /*no child*/
}
root = case_a(root, par, ptr);
else {
return root;
}
Threaded Tree Traversal Code
struct node *case_a(struct node *root, struct node *par, struct node *ptr) {
if(par==NULL) /*root node to be deleted*/
root=NULL;
else if(ptr==par->left) {
par->lthread=true;
par->left=ptr->left;
}
else {
par->rthread=true;
par->right=ptr->right;
}
free(ptr);
return root;
}
Threaded Tree Traversal Code
struct node *case_b(struct node *root, struct node *par, struct node *ptr) {
struct node *child,*s,*p;
/*Initialize child*/
if(ptr->lthread==false) /*node to be deleted has left child */
child=ptr->left;
else /*node to be deleted has right child */
child=ptr->right;
if(par==NULL) /*node to be deleted is root node*/
root=child;
else if(ptr==par->left) /*node is left child of its parent*/
par->left=child;
else /*node is right child of its parent*/
par->right=child;
s=in_succ(ptr);
p=in_pred(ptr);
if(ptr->lthread==false) /*if ptr has left subtree */
p->right=s;
else {
if(ptr->rthread==false) /*if ptr has right subtree*/
s->left=p;
}
free(ptr);
return root;
}
Threaded Tree Traversal Code
struct node *case_c(struct node *root, struct node *par, struct node *ptr) {
struct node *succ,*parsucc;
/*Find inorder successor and its parent*/
parsucc = ptr;
succ = ptr->right;
while(succ->left!=NULL) {
parsucc = succ;
succ = succ->left;
}
ptr->info = succ->info;
if(succ->lthread==true && succ->rthread==true)
root = case_a(root, parsucc,succ);
else
root = case_b(root, parsucc,succ);
return root;
}
Threaded Tree Traversal Code
struct node *in_succ(struct node *ptr) {
if(ptr->rthread==true)
return ptr->right;
else {
ptr=ptr->right;
while(ptr->lthread==false)
ptr=ptr->left;
return ptr;
}
}
8
3
1 5 7 11
9 13
Threaded Tree Traversal
Output
6 1
8
3
1 5 7 11
9 13
8
3
1 5 7 11
9 13
Follow thread to right, print node
Threaded Tree Traversal
Output
6 1
3
5
8
3
1 5 7 11
9 13
Follow link to right, go to leftmost
node and print
Threaded Tree Traversal
Output
1
6
3
5
8 6
3
1 5 7 11
9 13
Follow thread to right, print node
Threaded Tree Traversal
Output
6
1
3
8 5
3 6
7
1 5 7 11
9 13
9 13
9 13
9 13