Tree Data Structures
Tree Data Structures
• Binary Tree.
• Ternary Tree.
• N-ary Tree (Generic Tree)
• Binary Search Tree.
• AVL Tree.
• Red-Black Tree.
• B-Tree.
• B+ Tree.
Binary Tree
• A binary tree is a finite set of elements that is
either empty or is partitioned into three disjoint
subsets.
• The first subset contains a single element called
the root of the tree.
• The other two subsets are themselves binary
trees called the left and right subtrees.
• Each element of a binary tree is called a node of
the tree.
• Each node can have maximum two children.
Binary Tree
• Binary tree with 9 nodes.
A
B C
D E F
G H I
Binary Tree
root
B C
D E F
G H I
B C
D E F
Left subtree G H I
Right subtree
Binary Tree
• Recursive definition
A
B C
root
D E F
G H I
Left subtree
Binary Tree
• Recursive definition
A
B C
D E F
root
G H I
Binary Tree
• Recursive definition
A
root
B C
D E F
G H I
Right subtree
Binary Tree
• Recursive definition
A
B C
root
D E F
G H I
B C
D E F
G H I
Not a Tree
• Structures that are not trees.
A
B C
D E F
G H I
Not a Tree
• Structures that are not trees.
A
B C
D E F
G H I
Binary Tree: Terminology
parent
A
D E F
G H I
B C
D E J F
G K H I
Level of a Binary Tree Node
• The level of a node in a binary tree is
defined as follows:
Root has level 0,
Level of any other node is one more than the
level its parent (father).
• The depth of a binary tree is the maximum
level of any leaf in the tree.
Level of a Binary Tree Node
A 0 Level 0
B 1 C 1 Level 1
D 2 E 2 F 2 Level 2
G 3 H 3 I 3 Level 3
Complete Binary Tree
• A complete binary tree of depth d is the strictly
binary all of whose leaves are at level d.
0
A
B 1 C 1
D 2 E 2 F 2 G 2
H 3 I J 3 K L 3 M 3 N 3 O 3
Complete Binary Tree
A Level 0: 20 nodes
B C Level 1: 21 nodes
D E F G Level 2: 22 nodes
H I J K L M N O Level 3: 23 nodes
Complete Binary Tree
• At level k, there are 2k nodes.
• Total number of nodes in the tree of depth
d:
d
20+ 21+ 22 + ………. + 2d = 2j = 2d+1 – 1
j=0
n = 2d+1 – 1
or log2(n+1) = d+1
or d = log2(n+1) – 1
• I.e., the depth of the complete binary tree built
using ‘n’ nodes will be log2(n+1) – 1.
• For example, for n=1,000,000, log2(1000000) is
less than 20; the tree would be 20 levels deep.
Operations on Binary Tree
• There are a number of operations that can
be defined for a binary tree.
• If p is pointing to a node in an existing tree
then
left(p) returns pointer to the left subtree
right(p) returns pointer to right subtree
parent(p) returns the father of p
brother(p) returns brother of p.
info(p) returns content of the node.
Operations on Binary Tree
• In order to construct a binary tree, the
following can be useful:
• setLeft(p,x) creates the left child node of p.
The child node contains the info ‘x’.
• setRight(p,x) creates the right child node
of p. The child node contains the info ‘x’.
Applications of Binary Trees
• A binary tree is a useful data structure
when two-way decisions must be made at
each point in a process.
• For example, suppose we wanted to find
all duplicates in a list of numbers:
14
15 14
14
15
4 14
15
14
4 15
9 14
4 15
14
4 15
7 14
4 15
14
4 15
18 14
4 15
14
4 15
9 18
3 14
4 15
9 18
14
4 15
3 9 18
5 14
4 15
3 9 18
14
4 15
3 9 18
16 14
4 15
3 9 18
14
4 15
3 9 18
7 16
4 14
4 15
3 9 18
7 16
20 14
4 15
3 9 18
7 16
14
4 15
3 9 18
7 16 20
17 14
4 15
3 9 18
7 16 20
17, 9, 14, 5
Searching for Duplicates
14
4 15
3 9 18
7 16 20
5 17
17, 9, 14, 5
Searching for Duplicates
14
4 15
3 9 18
7 16 20
5 17
9, 14, 5
C++ Implementation
#include <stdlib.h>
template <class Object>
class TreeNode {
public:
// constructors
TreeNode()
{
this->object = NULL;
this->left = this->right = NULL;
};
TreeNode( Object* object )
{
this->object = object;
this->left = this->right = NULL;
};
C++ Implementation
Object* getInfo()
{
return this->object;
};
void setInfo(Object* object)
{
this->object = object;
};
TreeNode* getLeft()
{
return left;
};
void setLeft(TreeNode *left)
{
this->left = left;
};
C++ Implementation
TreeNode *getRight()
{
return right;
};
void setRight(TreeNode *right)
{
this->right = right;
};
int isLeaf( )
{
if( this->left == NULL && this->right == NULL )
return 1;
return 0;
};
C++ Implementation
private:
Object* object;
TreeNode* left;
TreeNode* right;
}; // end class TreeNode
C++ Implementation
#include <iostream>
#include <stdlib.h>
#include "TreeNode.cpp"
4 15
3 9 18
7 16 20
17, 9, 14, 5
Trace of insert
p
17 14
4 q 15
3 9 18
7 16 20
17, 9, 14, 5
Trace of insert
17 14
4 p 15
q
3 9 18
7 16 20
17, 9, 14, 5
Trace of insert
17 14
4 p 15
3 9 q 18
7 16 20
17, 9, 14, 5
Trace of insert
17 14
4 15
3 9 p 18
q
7 16 20
17, 9, 14, 5
Trace of insert
17 14
4 15
3 9 p 18
7 q 16 20
17, 9, 14, 5
Trace of insert
17 14
4 15
3 9 18
7 p 16 20
q
5
17, 9, 14, 5
Trace of insert
17 14
4 15
3 9 18
7 p 16 20
5 q
17, 9, 14, 5
Trace of insert
14
4 15
3 9 18
7 p 16 20
5 node 17
14
4 15
L left right R
subtree subtree
(L,N,R), (L,R,N)
(N,L,R), (N,R,L)
(R,L,N), (R,N,L)
Traversing a Binary Tree
• Three common ways
N node
left right
L subtree subtree R
Preorder: (N,L,R)
Inorder:
(L,N,R)
Postorder: (L,R,N)
Traversing a Binary Tree
14
4 15
3 9 18
7 16 20
5 17
Preorder: 14 4 3 9 7 5 15 18 16 17 20
Traversing a Binary Tree
14
4 15
3 9 18
20
7 16
5 17
Inorder: 3 4 5 7 9 14 15 16 17 18 20
Traversing a Binary Tree
14
4 15
3 9 18
20
7 16
5 17
Postorder: 3 5 7 9 4 17 16 20 18 15 14
Recursive Call
• Recall that a stack is used during function
calls.
• The caller function places the arguments
on the stack and passes control to the
called function.
• Local variables are allocated storage on
the call stack.
• Calling a function itself makes no
difference as far as the call stack is
concerned.
Stack Layout during a call
• Here is stack layout when function F calls
function F (recursively):
Parameters(F) Parameters(F) Parameters(F)
Local variables(F) Local variables(F) Local variables(F)
Return address(F) Return address(F) Return address(F)
sp
Parameters(F) Parameters(F)
sp
Local variables(F)
Return address(F)
sp
At point of call During execution of F After call
Recursion: preorder
14 preorder(14)
14
..preorder(4)
4 15 4
....preorder(3)
3
......preorder(null)
3 9 18 ......preorder(null)
....preorder(9)
9
7 16 20 ......preorder(7)
7
........preorder(5)
5 5
17 ..........preorder(null)
..........preorder(null)
........preorder(null)
......preorder(null)
Recursion: preorder
14 ..preorder(15)
15
....preorder(null)
4 15 ....preorder(18)
18
......preorder(16)
16
3 9 18 ........preorder(null)
........preorder(17)
17
7 16 20 ..........preorder(null)
..........preorder(null)
......preorder(20)
5 20
17 ........preorder(null)
........preorder(null)
Recursion: inorder
14 inorder(14)
..inorder(4)
....inorder(3)
4 15 ......inorder(null)
3
......inorder(null)
4
3 9 18 ....inorder(9)
......inorder(7)
........inorder(5)
7 16 20 ..........inorder(null)
5
..........inorder(null)
5 7
17 ........inorder(null)
9
......inorder(null)
14
Recursion: inorder
14 ..inorder(15)
....inorder(null)
15
4 15 ....inorder(18)
......inorder(16)
........inorder(null)
16
3 9 18 ........inorder(17)
..........inorder(null)
17
7 16 20 ..........inorder(null)
18
......inorder(20)
5 ........inorder(null)
17 20
........inorder(null)
Ternary Tree
5 0
2 8 1
1 4 7 2
3 3
AVL Tree
6 0
1 8 1
1 4 2
3 5 3
Red-Black Tree
• Another type of self-balancing binary search
tree that uses color properties (red or black)
to enforce balance during insertions and
deletions.
• Widely used in memory management and
data compression due to its balanced nature.
If data is inserted in a non-random sequence,
the tree might become unbalanced, seriously
degrading its performance.
A red-black tree can fix this by ensuring that the
tree remains balanced at all times.
• Let’s understand the different scenarios of a
binary search tree.
In the above tree, if we want to search the 80. We will first compare
80 with the root node and so on. The above BST will take O(logn) time to
search the element.
The above tree shows the right-skewed BST. If we want to search
the 80 in the tree, we will compare 80 with all the nodes until we
find the element or reach the leaf node. So, the above right-
skewed BST will take O(N) time to search the element.
We know the second rule of the Red Black tree that if the tree
is not empty then the newly created node will have
the Red color.
• Step 3: Now, we create the new node having
value 7 with Red color. As 7 is less than 10, so
it will come at the left of 10 as shown below.
• Step 4: The next element is 15, and 15 is
greater than 10, but less than 18, so the new
node will be created at the left of node 18.
The node 15 would be Red in color as the tree
is not empty.