Lecture 11 Complete Tree+Tree Traversal
Lecture 11 Complete Tree+Tree Traversal
Data Structures
Fall 2023
Binary Tree and Tree ADT
1
Binary Tree
• In a binary tree each node has at most two children
– Allows to label the children as left and right
2
Binary Tree: Full Node
• A full node is a node where both the left and right sub-trees are
non-empty trees
• (OR) if it has exactly two child nodes
3
Full Binary Tree
• A full binary tree is where each node is:
– A full node, or
– A leaf node
• Full binary tree is also called proper binary tree, strictly binary
tree or 2-tree
4
Perfect Binary Tree
• A perfect binary tree of height h is a binary tree where
– All leaf nodes have the same depth or level L
– All other nodes are full-nodes
5
Binary Tree: Properties (3)
• A perfect binary tree with height h has 2h leaf nodes
6
Binary Tree: Properties (4)
• A perfect binary tree with height h has 2h leaf nodes
7
Binary Tree: Properties (4)
• A perfect binary tree with height h has 2h leaf nodes
8
[Almost] Complete Binary tree
9
Almost (or Nearly) Complete Binary Tree
• Almost complete binary tree of height h is a binary tree in which
1. There are 2d nodes at depth d for d = 1,2,...,h−1
Each leaf in the tree is either at level h or at level h – 1
2. The nodes at depth h are as far left as possible
perfect binary
tree of height
h-1
Perfect binary
tree of height
h-1
13
Complete Binary Trees…
14
Complete Binary Tree: Properties
• Total number of nodes n are between
– At least: perfect binary tree of height h-1 + 1 (i.e., 1 node in
the next level) 2h – 1 + 1= 2h nodes
– At most: perfect binary tree of height h, i.e., 2h+1 -1 nodes
• Height h is equal to
15
Balanced Binary Tree
• Balanced binary tree
– For each node, the difference in height of the right and left sub-trees
is no more than one
– Both Perfect binary trees and complete binary trees are balanced as
well
16
Tree ADT
17
Binary Tree Storage
• Contiguous storage
• Linked-list based storage
19
Contiguous Storage
20
Array Storage Example (1)
A
[1] A
[2] B
B C [3] C
[4] D
[5] E
D E F G [6] F
[7] G
[8] H
H I [9] I
21
Array Storage (1)
• We can store a binary tree as an array
22
Array Storage (2)
• The children of the node with index k are in 2k and 2k + 1
• The parent of node with index k is in k ÷ 2
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
23
Array Storage Example (3)
• Node 10 has index 5
– Its children 13 and 23 have indices 10 and 11, respectively
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
24
Array Storage Example (4)
• Node 10 has index 5
– Its children 13 and 23 have indices 10 and 11, respectively
– Its parent is node 9 with index 5/2 = 2
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
25
Array Storage (3)
• Why array index is not started from 0
– In C++, this simplifies the calculations
parent = k >> 1;
left_child = k << 1;
right_child = left_child | 1;
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
26
Array Storage Example (2)
• Unused nodes in tree represented by a predefined bit pattern
A [1] A
[2] B
[3] -
B
[4] C
[5] -
C
[6] -
[7] -
D [8] D
[9] -
E … …
[16] E
27
Array Storage: Disadvantage
• Why not store any tree as an array using breadth-first traversals?
– Because there is a significant potential for a lot of wasted memory
28
Array Storage: Disadvantage
• Why not store any tree as an array using breadth-first traversals?
– There is a significant potential for a lot of wasted memory
29
Array Storage: Disadvantage
• Why not store any tree as an array using breadth-first traversals?
– There is a significant potential for a lot of wasted memory
30
Linked List Storage
31
As Linked List Structure (1)
• We can implement a binary tree by using a struct which stores:
– An element
– A left child pointer (pointer to first child)
– A right child pointer (pointer to second child)
struct Node{
Type value;
Node *LeftChild,*RightChild;
}*root;
32
As Linked List Structure: Example
Root pointer
b c
d e f
g h i j k
l
33
Tree Traversal
34
Tree Traversal
• To traverse (or walk ) the tree is to visit (printing or manipulating)
each node in the tree exactly once
– Traversal must start at the root node
There is a pointer to the root node of the binary tree
35
Breadth-First Traversal (For Arbitrary Trees)
• All nodes at a given depth d are traversed before nodes at d+1
• Can be implemented using a queue
• Order: A B H C D G I E F J K
36
Breadth-First Traversal – Implementation
• Create a queue and push the root node onto the queue
• While the queue is not empty:
– Enqueue all of its children of the front node onto the queue
– Dequeue the front node
37
Depth-First Traversal (For Arbitrary Trees)
• Traverse as much as possible along the branch of each child before
going to the next sibling
– Nodes along one branch of the tree are traversed before backtracking
38
Depth-First Tree Traversal (Binary Trees)
• For each node in a binary tree, there are three choices
– Visit the node first
– Visit the node after left subtree
– Visit the node after both the subtrees
39
Inorder Traversal
• Algorithm
1. Traverse the left subtree in inorder
2. Visit the root
3. Traverse the right subtree in inorder
A, B, C, D, E, F, G, H, I, J
40
Inorder Traversal
• Algorithm
1. Traverse the left subtree in inorder +
2. Visit the root
3. Traverse the right subtree in inorder * +
A B * E
• Example
– Left + Right
– [Left * Right] + [Left + Right] C D
– (A * B) + [(Left * Right) + E)
– (A * B) + [(C * D) + E]
41
Inorder Traversal – Implementation
void inorder(Node *p) const
{
if (p != NULL)
{
inorder(p->leftChild);
cout << p->info << " ";
inorder(p->rightChild);
}
}
void main () {
. . .
inorder (root);
}
42
Preorder Traversal
• Algorithm
1. Visit the node +
2. Traverse the left subtree
3. Traverse the right subtree * +
A B * E
• Example
– + Left Right
– + [ * Left Right] [+ Left Right] C D
– + ( * AB) [+ * Left Right E]
– +*AB + *C D E
43
Preorder Traversal – Implementation
void preorder(Node *p) const
{
if (p != NULL)
{
cout << p->info << " ";
preorder(p->leftChild);
preorder(p->rightChild);
}
}
void main () {
. . .
preorder (root);
}
44
Postorder Traversal
• Algorithm
1. Traverse the left subtree +
2. Traverse the right subtree
3. Visit the node * +
A B * E
• Example
– Left Right +
– [Left Right *] [Left Right+] + C D
– (AB*) [Left Right * E + ]+
– (AB*) [C D * E + ]+
– AB* C D * E + +
45
Postorder Traversal – Implementation
void postorder(Node *p) const
{
if (p != NULL)
{
postorder(p->leftChild);
postorder(p->rightChild);
cout << p->info << " ";
}
}
void main () {
. . .
postorder (root);
}
46
Example: Printing a Directory Hierarchy
• Consider the directory structure presented on the left
– Which traversal should be used?
/
usr/
bin/
local/
var/
adm/
cron/
log/
47
Any Question So Far?
48