2. Definition of Tree
• A tree is a set of linked nodes, such that
there is one and only one path from a
unique node (called the root node) to
every other node in the tree.
• A path exists from node A to node B if one
can follow a chain of pointers to travel
from node A to node B.
2
3. Paths
A set of linked nodes
D
F
A
G
E
B
There is one path from A to B
C
There is a path from D to B
There is also a second path
from D to B. 3
4. Paths (cont.)
D
F
A
G
E
B
C There is no path from C to any
other node.
4
5. Cycles
• There is no cycle (circle of pointers) in a
tree.
• Any linked structure that has a cycle would
have more than one path from the root
node to another node.
5
7. Tree Cannot Have a
Cycle
D
A
B
C
E
2 paths exist from A to C:
1. A → C
2. A → C → D → B → E → C
7
8. Example of a Tree
In a tree, every
root pair of linked
A nodes have a
parent-child
relationship (the
C B D parent is closer
to the root)
G
E F
8
9. Example of a Tree
(cont.)
root For example, C is a
A parent of G
C B D
G
E F
9
10. Example of a Tree
(cont.)
root
A E and F are
children of D
C B D
G
E F
10
11. Example of a Tree
(cont.)
The root node is the
root
A only node that has no
parent.
C B D
G
E F
11
12. Example of a Tree
(cont.)
Leaf nodes (or
root leaves for short)
A
have no children.
C B D
G
E F
12
13. Subtrees
A subtree is a part of a tree
root
that is a tree in itself
A
B C
I K D E F
J
G H
subtree
13
14. Binary Trees
• A binary tree is a tree in which each node
can only have up to two children…
14
15. NOT a Binary Tree
root C has 3 child nodes.
A
B C
I K D E F
J
G H
15
16. Example of a Binary Tree
The links in a tree
root
are often called
A edges
B C
I K E
J G H
16
17. Levels
root
level 0 A
level 1 B C
level 2
I K E
level 3
J G H
The level of a node is the number of edges in the path
from the root node to this node
17
18. Full Binary Tree
root A
B C
D E F G
H I J K L M N O
In a full binary tree, each node has two children except for
the nodes on the last level, which are leaf nodes
18
19. Complete Binary Trees
• A complete binary tree is a binary tree
that is either
– a full binary tree
– OR
– a tree that would be a full binary tree but it is
missing the rightmost nodes on the last level
19
20. NOT a Complete Binary Trees
root A
B C
D E F G
H I Missing non-rightmost
nodes on the last level
20
21. Complete Binary Trees
(cont.)
root A
B C
D E F G
H I J K L Missing rightmost
nodes on the last
level
21
22. Complete Binary Trees
(cont.)
A full binary tree is
also a complete binary
root A tree.
B C
D E F G
H I J K L M N O
22
23. Binary Search Trees
• A binary search tree is a binary tree that
allows us to search for values that can be
anywhere in the tree.
• Usually, we search for a certain key
value, and once we find the node that
contains it, we retrieve the rest of the info
at that node.
• Therefore, we assume that all values
searched for in a binary search tree are
distinct.
23
24. Properties of
Binary Search Trees
• A binary search tree does not have to be a
complete binary tree.
• For any particular node,
– the key in its left child (if any) is less than its
key.
– the key in its right child (if any) is greater than
its key.
24
25. Binary Search Tree
Node
The implementation
template <typename T> of a binary search
BSTNode { tree usually just
T info; maintains a single
BSTNode<T> *left; pointer in the private
BSTNode<T> *right; section called
}; root, to point to the
root node.
25
26. Inserting Nodes
Into a BST
root:
NULL
BST starts off empty
Objects that need to be inserted (only key values are
shown):
37, 2, 45, 48, 41, 29, 20, 30, 49, 7
26
27. Inserting Nodes
Into a BST (cont.)
root
37
37, 2, 45, 48, 41, 29, 20, 30, 49, 7
27
28. Inserting Nodes
Into a BST (cont.)
root
37
2 < 37, so insert 2 on the
left side of 37
2, 45, 48, 41, 29, 20, 30, 49, 7
28
29. Inserting Nodes
Into a BST (cont.)
root
37
2
2, 45, 48, 41, 29, 20, 30, 49, 7
29
30. Inserting Nodes
Into a BST (cont.)
root
37
2
45 > 37, so insert it at the right of 37
45, 48, 41, 29, 20, 30, 49, 7
30
31. Inserting Nodes
Into a BST (cont.)
root
37
45
2
45, 48, 41, 29, 20, 30, 49, 7
31
32. Inserting Nodes
Into a BST (cont.)
root
37
45
2
When comparing, we always
start at the root node
48 > 37, so look to the right
48, 41, 29, 20, 30, 49, 7
32
33. Inserting Nodes
Into a BST (cont.)
root
37
45
2
This time, there is a node already
to the right of the root node. We
then compare 48 to this node
48 > 45, and 45 has no right
child, so we insert 48 on the right
of 45
48, 41, 29, 20, 30, 49, 7
33
34. Inserting Nodes
Into a BST (cont.)
root
37
45
2
48
48, 41, 29, 20, 30, 49, 7
34
35. Inserting Nodes
Into a BST (cont.)
root
37
45
2
41 > 37, so look to
the right 48
41 < 45, so look to
the left – there is no
left child, so insert
41, 29, 20, 30, 49, 7
35
36. Inserting Nodes
Into a BST (cont.)
root
37
45
2
48
41
41, 29, 20, 30, 49, 7
36
37. Inserting Nodes
Into a BST (cont.)
root
37
45
2
48
29 < 37, left 41
29 > 2, right
29, 20, 30, 49, 7
37
38. Inserting Nodes
Into a BST (cont.)
root
37
45
2
48
29 41
29, 20, 30, 49, 7
38
39. Inserting Nodes
Into a BST (cont.)
root
37
45
2
48
20 < 37, left 29 41
20 > 2, right
20 < 29, left
20, 30, 49, 7
39
40. Inserting Nodes
Into a BST (cont.)
root
37
45
2
48
29 41
20
20, 30, 49, 7
40
46. Inserting Nodes
Into a BST (cont.)
root
37
45
2
48
29 41
20 30 49
7
7
46
47. Inserting Nodes
Into a BST (cont.)
root
37
45
2
48
29 41
All elements have
20 30 49
been inserted
7
47
48. Searching for a
Key in a BST
root
37
45
2
48
29 41
Searching for a
key in a BST uses
20 30 49
the same logic
7
Key to search for: 29
48
49. Searching for a
Key in a BST (cont.)
root
37
45
2
48
29 < 37 29 41
20 30 49
7 Key to search for: 29
49
50. Searching for a
Key in a BST (cont.)
root
37
45
2
48
29 > 2 29 41
20 30 49
7 Key to search for: 29
50
51. Searching for a
Key in a BST (cont.)
root
37
45
2
48
29 == 29 29 41
FOUND IT!
20 30 49
7 Key to search for: 29
51
52. Searching for a
Key in a BST (cont.)
root
37
45
2
48
29 41
20 30 49
7 Key to search for: 3
52
53. Searching for a
Key in a BST (cont.)
root
37
45
2
3 < 37
3>2
48
3 < 29 29 41
3 < 20
3<7
20 30 49
7 Key to search for: 3
53
54. Searching for a
Key in a BST (cont.)
root
37
45
2
When the child pointer
you want to follow is
set to NULL, the key 48
29 41
you are looking for is
not in the BST
20 30 49
7 Key to search for: 3
54
55. Deleting a BST Node
• Deleting a node in a BST is a little tricky –
it has to be deleted so that the resulting
structure is still a BST with each node
greater than its left child and less than its
right child.
• Deleting a node is handled differently
depending on whether the node:
– has no children
– has one child
– has two children
55
56. Deletion Case 1:
No Children
root
37
45
2
48
29 41
Node 49 has no
children – to
20 30 49
delete it, we just
remove it
56
57. Deletion Case 1:
No Children (cont.)
root
37
45
2
48
29 41
20 30
57
58. Deletion Case 2:
One Child
root
37
45
2
48
29 41
Node 48 has one
child – to delete
20 30 it, we just splice 49
it out
58
59. Deletion Case 2:
One Child (cont.)
root
37
45
2
48
29 41
Node 48 has one
child – to delete
20 30 it, we just splice 49
it out
59
60. Deletion Case 2:
One Child (cont.)
root
37
45
2
29 41
20 30 49
60
61. Deletion Case 2:
One Child (cont.)
root
37
45
2
48
29 41
Another example:
node 2 has one child
20 30 – to delete it we also 49
splice it out
61
62. Deletion Case 2:
One Child (cont.)
root
37
45
2
48
29 41
Another example:
node 2 has one child
20 30 – to delete it we also 49
splice it out
62
63. Deletion Case 2:
One Child (cont.)
root
37
45
48
29 41
20 30 49
63
64. Deletion Case 3:
Two Children
root
37
45
2
48
29 41
Node 37 has two
children…
20 30 49
64
65. Deletion Case 3:
Two Children (cont.)
root
37
45
2
48
29 41
to delete it, first we
find the greatest
20 30 node in its left 49
subtree
65
66. Deletion Case 3:
Two Children (cont.)
root
37
45
2
First, we go
to the left 48
29 41
once, then
follow the
right pointers
as far as we 20 30 49
can
66
67. Deletion Case 3:
Two Children (cont.)
root
37
45
2
48
29 41
30 is the greatest
20 30 node in the left 49
subtree of node 37
67
68. Deletion Case 3:
Two Children (cont.)
root
37
45
2
48
29 41
Next, we copy the
20 30 object at node 30 49
into node 37
68
69. Deletion Case 3:
Two Children (cont.)
root
30
45
2
48
29 41
Finally, we delete
the lower red node
20 using case 1 or 49
case 2 deletion
69
70. Deletion Case 3:
Two Children (cont.)
root
30
45
2
48
29 41
Let’s delete node 30
20 now 49
70
71. Deletion Case 3:
Two Children (cont.)
root
30
45
2
48
29 41
29 is the greatest node
in the left subtree of
20 49
node 30
71
72. Deletion Case 3:
Two Children (cont.)
root
30
45
2
48
29 41
Copy the object at node
29 into node 30
20 49
72
73. Deletion Case 3:
Two Children (cont.)
root
29
45
2
48
29 41
This time, the lower red
node has a child – to delete
20 49
it we use case 2 deletion
73
74. Deletion Case 3:
Two Children (cont.)
root
29
45
2
48
29 41
This time, the lower red
node has a child – to delete
20 49
it we use case 2 deletion
74
75. Deletion Case 3:
Two Children (cont.)
root
29
45
2
48
41
20 49
75
76. Traversing a BST
• There are 3 ways to traversal a BST (visit
every node in BST):
• 1. Preorder (parent → left → right)
• 2. Inorder (left → parent → right)
• 3. Postorder (left → right → parent)
76
80. Printing Elements
In Order
2 void inOrderTraversal() The client uses the
3 { driver called
4 inOrderInternal (root); InOrderTraversal.
5 }
The recursive function
inOrderInternal is called.
inOrderInternal prints all
element in BST in sorted
order, starting from root
node.
80
81. Printing Elements
In Order (cont.)
2 void inOrderInternal (BSTNode<T> *parent)
3 {
4 if (parent != NULL) {
5 inOrderInternal (parent->left);
6 cout << parent->info << " ";
The base case
7 inOrderInternal (parent->right);
occurs when
8 }
parent is NULL –
9 }
just returns.
81
82. Printing Elements
In Order (cont.)
2 void inOrderInternal (BSTNode<T> *parent)
3 {
4 if (parent != NULL) { There are 2
5 inOrderInternal (parent->left); recursive calls
under the if – the
6 cout << parent->info << " ";
first advances
7 inOrderInternal (parent->right); the pointer to the
8 } left child…
9 }
and the second
advances the
pointer to the
right child.
82
83. Printing Elements
In Order (cont.)
2 void inOrderInternal (BSTNode<T> *parent)
3 {
4 if (parent != NULL) { Each recursive
5 inOrderInternal (parent->left); call approaches
6 cout << parent->info << " "; the base case…
7 inOrderInternal (parent->right); it goes down one
8 } level through the
9 } tree, and it get
closer to the
case where
parent->left or
parent->right is
NULL. 83
84. Printing Elements
In Order (cont.)
2 void inOrderInternal (BSTNode<T> *parent)
3 {
If the BST contains
4 if (parent != NULL) {
only one node, the
5 inOrderInternal (parent->left);
root node is the only
6 cout << parent->info << " ";
node – the left and
7 inOrderInternal (parent->right);
right pointers of the
8 }
root node will be set
9 }
to NULL.
84
85. Printing Elements
In Order (cont.)
2 void inOrderInternal (BSTNode<T> *parent)
3 {
4 if (parent != NULL) { parent->left is
5 inOrderInternal (parent->left); NULL, so NULL is
passed into
6 cout << parent->info << " ";
parent of the new
7 inOrderInternal (parent->right);
inOrderInternal
8 }
function.
9 }
85
86. Printing Elements
In Order (cont.)
2 void inOrderInternal (BSTNode<T> *parent)
3 {
Since parent is
4 if (parent != NULL) {
NULL in the new
5 inOrderInternal (parent->left);
inOrderInternal
6 cout << parent->info << " ";
function, it will
7 inOrderInternal (parent->right);
return right away.
8 }
9 }
86
87. Printing Elements
In Order (cont.)
2 void inOrderInternal (BSTNode<T> *parent)
3 {
4 if (parent != NULL) { parent->right is
5 inOrderInternal (parent->left); NULL – thus,
6 cout << parent->info << " "; the recursive
7 inOrderInternal (parent->right); function call
immediately
8 }
returns as
9 }
before.
87
88. Printing Elements
In Order (cont.)
2 void inOrderInternal (BSTNode<T> *parent)
3 {
4 if (parent != NULL) {
5 inOrderInternal (parent->left);
6 cout << parent->info << " ";
7 inOrderInternal (parent->right);
8 }
9 }
In fact inOrderInternal works correctly when
there is only 0, 1 or many node in the BST.
88
89. Printing Elements
In Order (cont.)
2 void inOrderInternal (BSTNode<T> *parent)
3 {
4 if (parent != NULL) {
5 inOrderInternal (parent->left);
6 cout << parent->info << " ";
7 inOrderInternal (parent->right);
8 }
9 }
inOrderInternal is called once from the driver
inOrderTraversal. Then, for each node in the tree, 2
calls to inOrderInternal are made, giving us a total
of 2n + 1 calls where n is the number of nodes. 89
90. Printing Elements
Pre Order
2 void preOrderInternal (BSTNode<T> *parent)
3 {
4 if (parent != NULL) {
5 cout << parent->info << " ";
6 preOrderInternal (parent->left);
7 preOrderInternal (parent->right);
8 }
9 }
preOrderInternal prints the parent first.
90
91. Printing Elements
Post Order
2 void postOrderInternal (BSTNode<T> *parent)
3 {
4 if (parent != NULL) {
5 postOrderInternal (parent->left);
6 postOrderInternal (parent->right);
7 cout << parent->info << " ";
8 }
9 }
postOrderInternal prints the parent last.
91
93. Searching and Insertion in BST
• We can actually figure out searchInternal
and insertInternal using the same
recursive logic as traversal in BST.
93
94. References
• Childs, J. S. (2008). Trees. C++ Classes
and Data Structures. Prentice Hall.
94