2. Today’s
Discussion
…
We will cover:
Definition of a tree data structure
and its components.
Definition of binary tree.
Binary Search Tree Operations
Searching for an item
Inserting a new item
Deleting an item
Finding the minimum and maximum items
Binary Search Tree Traversals:
A means of visiting all the objects in a tree data structure
We will look at
Breadth-first traversals
Depth-first traversals
3. Tree Data Structure
It is a non-linear collection of data items, also linked together with pointers like a linked list.
Each node may contain 2 or more pointers to other nodes.
root ptr
-33
5
17
53 91 -115
NULL
NULL NULL
NULL NULL
NULL NULL
Root node
L child R child
Leaf node
NULL
Empty tree
4. Tree Terminology
Every tree has a "root" pointer.
The top node of a tree is called its "root" node.
Root: a node without a parent Ex: A is the root
Internal node: a node with at least one child
Ex: A, B, C, F are internal nodes
Leaf (External node): a node without children or
Nodes with degree zero . Ex: E, I, J, K, G, H, D are leaves
Ancestors of a node: parent, grandparent, great-grandparent, etc.
Ex: K’s ancestors are F
, B, and A
4
A
B D
C
G H
E F
I J K
5. Siblings: nodes that have the same parent
Ex: E and F; I, J, and K; G and H; B, C and D
Descendant of a node: child, grandchild, great-grandchild, etc.
Ex: B’s descendants are E, F
, I, J and K
Subtree: tree consisting of a node and its descendants
(Right subtree, Left subtree)
Edge: a pair of nodes (𝐶, 𝐻) such that 𝐶 is a parent of 𝐻
((𝐶, 𝐻))
Path: A sequence of nodes such that any two consecutives nodes form an edge (𝐴,
𝐵, 𝐹, 𝐽)
A tree with no nodes is called an “empty tree”
The degree of a node is defined as the number of its children : deg(A) = 3
A
B D
C
G H
E F
I J K
6. Height of a node : number of levels – 1
Or number of edges in the path from the node to leaf node
For each node in a tree, there exists a unique path from the root node to that node.
The length of this path is the depth of the node, e.g.,
E has depth 2
L has depth 3
For convenience, we define the height of the empty tree to be –1
MAX Height of a tree: maximum depth of that tree.
tre
e
Size of : number of nodes in
tree tree
Length of : the longest path from root to
leaf
depth of a node : number of ancestors
or number of edges in the path from the root to that
node
11. Each node Implementation
struct
TreeNode
{ InfoNode info
; //
Data member
TreeNode
* left
; //
Pointer to left child
TreeNode
*
;}
right
; //
Pointer to right child
.
left
.
info
.
right
NULL 6000
Data
12. Binary
Tree
Complete Binary Tree: let ℎ be the height of the tree
for 𝑖 = 0 … ℎ − 1, there are 2𝑖 nodes on level 𝑖
at level ℎ, nodes are filled from left to right
The order is identical to that of a breadth-first traversal
Perfect binary
trees are balanced
while linked lists
are not
14. 4
1
Operations on Binary
Trees
• Searching for an item
• Adding a new item at a certain position on the tree
• Deleting an item
• Binary Tree Traversals:
• Breadth-first traversals BFS
(Level-order traversal)
• Depth-first traversals DFS
1. Pre-order traversal
2. In-order traversal
3. Post-order traversal
NULL
“a”
NULL
NULL NULL NULL NULL
root
16. Binary Search Trees BST
•
Binary Search Trees are a type of binary tree with specific properties that make
them very efficient to search for a value in the tree
.
Binary Search Tree Property
:
The value stored at a node is greater than the value stored
at its left child and less than the value stored at its right
child
Thus, the value stored at the root of a subtree is greater than
any value in its left subtree and less than any value in its
right subtree
!!
3
5
7
2 4 9
Here’s an example BST…
Binary search - finds a path through the tree, starting
at the "root", and each chosen path (left or right
node) eliminates half of the stored values.
Very useful for fast searching and sorting of data,
assuming the data is to be kept in some kind of order.
19. Operations on a Binary Search Tree
Search in the binary search tree for a value
Insert an item in the binary search tree
Delete an item from the binary search tree
Traverse the binary search tree
Finding the Minimum in a Binary Search Tree
Finding the Maximum in a Binary Search Tree
20. 1
-
Searching for a
Key
Idea
Starting at the root: trace down a path by
comparing k with the key of the current node(Keep
going until we hit the NULL pointer)
If the keys are equal: we have found the key DONE!
(nothing to do...)
If k < key[x] search in the left subtree of x
If k > key[x] search in the right subtree of x
If we hit a NULL pointer, not found.
3
2 4
6
15
18
20
7
17
13
9
Search for key 13:
15 6 7 13
current node value x
21. Big Oh of BST
Search
Question:
In the average BST with N values,
how many steps are required to
find our value?
Right! log(N) steps
Running Time: O (h),
h – the height of the
tree
Question:
In the worst case BST with
N values, how many steps are
required find our value?
Right! N steps
WOW!
Now that’s!
50% eliminated!
50%
eliminated
!
50%
eliminated
!
50%
eliminated
!
Is this better than searching a linked list? Yes !! ---> O(logN)
22. BST Search(find)
Implementation
node* search_N(node* root, int x)
{
if(root == NULL)
{
cout<< "the key not exist";
return NULL;
}
if (root->data == x)
{cout<< "the key is :"<<x;
return root;}
else if(x < root->data)
root->left= search_N(root->left, x);
else if(x > root->data)
root->right= search_N(root-
>right, x);
}
23. 2
-
Insertion
Goal:
Insert value v into a binary search tree
Idea:
If the tree is empty
Allocate a new node and put V into it
Point the root pointer to our new node. DONE!
Start at the root
- If current node value x < v move to the right child of x,
else move to the left child of x
- When x is NULL, we found the correct position
2
1 3
5 18
19
9 15
13
17
Insert value 13
12
25. Yes, certain orders produce very unbalanced trees!!
Unbalanced trees are not desirable because search time
increases!!
There are advanced tree structures (e.g.,"red-black
trees, AVL tree") which guarantee balanced trees
Does the order of inserting
elements into a tree matter
?
To insert a new node in our BST
, we must place the
new node so that the resulting tree is still a valid
BST!
26. 25
Big Oh of BST
Insertion
So, what’s the big-oh of BST Insertion?
Right! It’s also O(log n)
Why? Because we have to first use a binary search to find where to insert our
node and binary search is O(log n).
28. Function
Delete Item
First, find the item; then, delete
it
Important: binary search tree
property must be preserved!!
We need to consider three different
cases:
• (1) Deleting a leaf
• (2) Deleting a node with only one child
• (3) Deleting a node with two children
29. Deletion
Goal:
Delete a given node z from a binary search tree
Idea:
Case 1: z has no children
Delete z by making the parent of z point to NulL
15
16
20
23
6
5
12
3
7
10 13 18
delete
15
16
20
18 23
6
5
12
3
7
10
z
If the node was found,
delete it from the tree,
making sure to
preserve its ordering!
30. 29
Case 2: z has one child
Delete z by making the parent of z point to z’s child, instead of to z
15
20
18 23
6
5
12
3
7
10 13
delete
z
16
15
20
18 23
6
5
12
3
7
10
31. Case 3: z has two children
By choosing the minimum node in z’s right subtree or
By choosing the maximum node in z’s left subtree
15
16
20
18 23
6
12
3
7
10 13
delete z
5
y
15
16
20
18 23
7
6
12
3
10 13
6
33. Tree
Traversal
s
There are mainly three ways
to
traverse a tree:
Breadth First (Level Order BFS)
Inorder Traversal
Postorder Traversal
Preorder Traversal
34. Each technique differs in the order that each node is visited during the traversal:
• Breadth-first traversals BFS
(Level-order traversal)
• Depth-first traversals DFS
1. Pre-order traversal
2. In-order traversal
3. Post-order traversal
A means of visiting all the nodes in a tree data structure
Any time we traverse through a tree, we always start with the root node.
There are 2 common ways to traverse a tree
.
35. Breadth-First Traversal BFS
Level-order Traversal: Level-by-
level
:
The breadth-first traversal visits all nodes
at depth k before proceeding onto depth k + 1
Easy to implement using a queue
Run time is O(n)
To determine the order of nodes visited in a level-order traversal…
Start at the top node and draw a horizontal line left-to-right through
all nodes on that row.
Repeat for all remaining rows.
The order you draw the lines is the order of the level-order
traversal!
Another approach is to visit always go as deep as possible before
visiting other siblings: depth-first traversals
Level-order:
A B H C D G I E H J K
36. Array
storage
We can store this in an array after a quick traversal: To insert another node while maintaining the complete-
binary-tree structure, we must insert into the next array
location
37. BST BFS
Implementation
void BFS_level_order()
{
if (root == NULL) return;
queue < node*> q;
q.push(root);
while(!q.empty())
{
node *current= q.front();
if (current->left!= NULL)
q.push(current->left);
if (current->right!= NULL)
q.push(current->right);
cout<<current->data<<" ";
q.pop();
} cout<<endl;}
The implementation was already discussed:
• Create a queue and push the root node
onto the queue
• While the queue is not empty:
Push all of its children of the front node
onto the queue
Pop the front node
38. ‘J’
‘E’
‘A’ ‘H’
‘T’
‘M’ ‘Y’
tree
Visit left subtree first Visit right subtree last
Visit second
Inorder Traversal:
Visit the nodes in the left subtree,
then visit the root of the tree,
then visit the nodes in the right
subtree .
(Warning:
"visit" means that the algorithm
does something with the
values
in the node, e.g., print the
value)
A E H J M T Y
• An inorder traversal of a BST
visits the keys in ascending
order
Hint: use binary search trees for
sorting !!
Depth-first Traversal
39. ‘J’
‘E’
‘A’ ‘H’
‘T’
‘M’ ‘Y’
tree
Visit left subtree first Visit right subtree second
Visit last
Postorder
A H E M Y T
J
Visit the nodes in the left subtree first,
then visit the nodes in the right subtree,
then visit the root of the tree
40. Visit right subtree last
39
J E A H T M Y
Preorder
Traversal
:
‘J’
‘E’
‘A’ ‘H’
‘T’
‘M’ ‘Y’
tree
Visit left subtree second
Visit first
Visit the root of the tree first,
then visit the nodes in the left subtree,
then visit the nodes in the right subtree
43. Finding the Minimum and Maximium in a BST
Goal: find the minimum value in a BST
Following left child pointers from the root,
until a NIL is encountered
2 4
Running time: O(h), h – height of tree
15
6 18
3 7 17 20
13
9
Minimum = 2
Goal: find the maximum value in a BST
Following right child pointers from the root,
until a NIL is encountered
Running time: O(h), h – height of tree
3
2 4
6
15
18
20
7
17
13
9
Maximum = 20
44. Begin from root
Hopefully you’re getting the idea that most tree functions can be done
recursively…
Finding Min & Max of a
BST
And here are recursive versions for you…
node* findMin(node* t)
{
if(t == NULL)
return NULL;
else if(t->left == NULL)
return t;
else
return findMin(t->left);
}
node* findMax(node* t)
{
if(t == NULL)
return NULL;
else if(t->right == NULL)
return t;
else
return findMax(t-
>right) }
45. Binary Search Trees -
Summary
SEARCH
INSERT
DELETE
MINIMUM
MAXIMUM
Operations on binary search trees:
O(h)
O(h)
O(h)
O(h)
O(h)
These operations are fast if the height
of the tree is small – otherwise their
performance is similar to that of a linked list
Running time of basic operations on BST (logn)
The expected height of the tree is log(n)
In the worst case: (n)
The tree is a linear chain of n
nodes
47. In real life, BSTs often end up
looking just unbalanced,
especially after repeated
insertions and deletions
Balanced Search
Trees
It’d be nice if we could come
up with an improved BST ADT
that always maintains its
balance.
This would ensure that all insertions,
searches and deletions would be O(log
n).
48. Why AVL Trees?
Most of the BST operations (e.g., search, max, min, insert, delete.. etc)
take O(h) time where h is the height of the BST.
The cost of these operations may become O(n) for a skewed Binary
tree. If we make sure that height of the tree remains O(Logn) after
every insertion and deletion, then we can guarantee an upper bound
of O(Logn) for all these operations.
The height of an AVL tree is always O(Logn) where n is the number of
nodes in the tree
Thus, our goal is to keep the height of a binary search tree O(log N)
Such trees are called balanced binary search trees.
Examples are AVL tree, red-black tree
49. Does the order of inserting
elements into a tree matter
?
• Yes, certain orders produce very unbalanced trees!!
• Unbalanced trees are not desirable because search time
increases!!
• There are advanced tree structures (e.g.,"Adelson-Velskii and
Landis") which guarantee balanced trees
• An AVL-tree is a BST with the property that at every node the
difference in the height of the left and right subtree is at most 1.
50. Definition of an AVL tree
AVL tree is a self-balancing Binary Search Tree (BST) where the
difference between heights of left and right subtrees cannot be
more than one for all nodes.
- Every sub-tree is an AVL tree
In BST, we said when data are
almost sorted, The shape is like
a branch (Linked list)
The problem is all operations
are O(N) We wish a tree be balanced
Its height is minimal
Minimal height is log(N)
20
15
25
20
30
15
10
25
10
30
51. AVL Tree
• To solve this problem, many binary trees were proposed to solve this problem
automatically
• These trees are called balanced binary search trees
• One of the first and simplest trees is AVL tree
• AVL says ONCE a tree is unbalanced, we simply find our way to rebalance it
• In AVL, this is highlighted when the difference between Left Hight and Right
Hight ≤ |1|
• Define “balanced factor” of a node to be the absolute difference in heights
between left and right sub trees
• AVL tree is defined as a tree such that, for each node, |balanced factor| ≤1
52. AVL Balanced Example
15
10
20
7 12
16
Right length (e.g. 15-20-16) = 2 steps
Left length (e.g. 15-10-7)= 2 steps
left – right = 0 < 1
15
10
20
7 12
16
left length (e.g. 15-10-12-13) = 3 steps
right length (e.g. 15-20-16)= 2 steps
Longest – Shortest = 1
13
53. Best Balanced Example
16
10
20
7 12
16
13
Note, the optimal tree could be
built by centralizing the numbers
when are sorted in BST
However, AVL doesn’t care
when difference = 0 or 1
AVL Unbalanced Example
15
10
20
7
12 16
13
left Path (e.g. 15-10-12-13-14) = 4 steps
right path (e.g. 15-20-16)= 2 steps
Longest – Shortest = 2 => unbalance
14
54. AVL Balance Factor
To detect the unbalance:
• we calculate the balance factor BF
• Leaf node factor = 0
• balance factor = left height – right height
• If factor > 1, left is bigger
• If factor < -1, right is bigger
The factor helps us to know if there is a problem or not
15
10
20
7 12
16
13
Bf = 0
Bf = -1
55. AVL Balance Factor
• Once we added a node, we goes up and update the BF, once |
BF| > 1, we know we have a problem starting from this node, then
we fix it.
• To rebalance, we apply tree rotation concept
15
10
20
7 12
16
13
Bf = 0
Bf = -1
Bf = 0
14
Bf = -2
15
10
20
7 13
16
14
Bf = 0 Bf = 0
12
Bf = 0
Bf = -1
Bf = 1
56. Think in 3 nodes => 4 cases
• In a bigger tree, each node of the 3 might
have 0-2 children.
• When doing the balance, make sure the
sub-trees are re-allocated without violating
a BST
5
3
4
3
5
4
5
4
3
3
4
5
5
3
4
1-Left Left 2-Right Right 3-Left Right 4-Right Left
Bf = 2 Bf = -2
Bf = 2 Bf = -2
Bf = 1
Bf = -1
Bf = -1 Bf = 1
+ve => Left -ve => Right
57. LR => LL => Balanced
Left Rotation Right Rotation
Imagine that: A, B, C, D are possible 4 sub-trees
We would like to do rotations to balance the 3 nodes causing a problem
But keep the BST property correct
You may think: A = 2, B = 3.5, C = 4.5, D = 6
58. RL => RR => B
Left Rotation
If you checked to the A, B, C, D order in the 3 shapes,
you will find them sorted
Right Rotation
68. Insertion Implementation
• The AVL is very easy in implementation
• Same insertion as in BST
• inserting a new element as a leaf may break the balance of the tree.
• We could update height after insertion
• Then calc the BF, if |BF| < 1 => balance
• If not balanced, rebalanced it by rotation
1) Left Rotation
2) Right Rotation
• The magic concept is rotation. A rotation rearranges
a BST, but preserve the BST property
70. int height(Node *N)
{
if (N == NULL)
return -1; //empty tree
else
{
int left_subtree= height(N->left);
int right_subtree= height(N->right);
return
(max_fun(left_subtree,right_subtree)) + 1;
}
int max_fun(int a, int b)
{
return (a > b)? a : b;
}
71. //3. Get the BF factor
int BF = getBalance(t);
// If this t becomes unbalanced,
then there are 4 cases
// Left Left Case
if (BF > 1 && x < t->left->Data)
return rightRotate(t);
// Right Right Case
if (BF < -1 && x > t->right->Data)
return leftRotate(t);
// Left Right Case
if (BF > 1 && x > t->left->Data)
{
t->left = leftRotate(t->left);
return rightRotate(t);
}
// Right Left Case
if (BF < -1 && x < t->right-
>Data)
{
t-> right = rightRotate(t-
>right);
return leftRotate(t);
}
return t;
}
// Get Balance factor of node
N
int getBalance(Node *N)
{
if (N == NULL)
return 0;
return height(N->left) -
height(N->right);
}
78. Deletion Implementation
Node* remove_n(int x, Node* t) {
Node* temp;
if(t == NULL)
return NULL;
else if(x < t->Data)// search data
t->left = remove_n(x, t->left);
else if(x > t->Data)
t->right = remove_n(x, t->right);
else // found data
{ // node with only one child or no child
temp = t;
if(temp->left == NULL)
{
temp = temp->right;
delete t;
return temp;
}
else if(temp->right == NULL)
{temp = temp->left;
delete t;
return temp;}
// node with two children
else{
temp = findMin(t->right);
t->Data = temp->Data;
t->right = remove_n(t->Data, t->right);
}
}
return t;
/* 2. Update height of this ancestor node */
t->height = 1 + max_fun(height(t->left),height(t-
>right));
//3. Get the BF factor
int BF = getBalance(t);
79. if (BF > 1 && x < t->left->Data)
return rightRotate(t);
// Right Right Case
if (BF < -1 && x > t->right->Data)
return leftRotate(t);
// Left Right Case
if (BF > 1 && x > t->left->Data)
{
t->left = leftRotate(t->left);
return rightRotate(t);
}
// Right Left Case
if (BF < -1 && x < t->right->Data)
{
t->right = rightRotate(t->right);
return leftRotate(t);
}
return t;
}
80. Conclusion
• Now, we are ready for a full example trace
• The flow is simple
• 1- Add the element to the BST in normal way
• 2- Let current node = just added one
• 3- Calculate BF
• 4- if |BF| > 1, we have an AVL unbalance
• If we are in case (3 or 4), convert to case (1 or 2)
• If new in case 1 or 2, handle them
• Let current node = parent
• Go to 3
In delete element, Same steps as in BST
Start from where the node deleted (according to the 3 cases)
and behave as the insertion in AVL( calc BF and do rotations if |
BF| > 1)
#60:Input rearranged from an AVL lecture from CodeMasry Channel
Channel input: 100 120 140 80 60 90 130 145 135 110 137
Thanks for them
#77:OK, if we have a bit of extra time, do this.
Let’s try deleting.
15 is easy! It has two children, so we do BST deletion.
17 replaces 15.
15 goes away.
Did we disturb the tree?
NO!