Lecture 8:
Data Structures (Trees)
Binary Tree
2
Definition of Tree
3
Tree Examples
4
Definition of Binary Tree
r
TL
TR
5
Announcement
6
An Example of Binary Tree
7
Height of a Tree
Height: 3
Height: 5
Height: 7
8
Full Binary Tree
Full BT of
Height 0
Full BT of
Height 1
Full BT of
Height 2
Full BT of
Height 3
Full BT of Height 4
So now, you may feel why this is called full binary tree:
it is filled with nodes at all possible positions!
9
Complete Binary Tree
Complete BT of
Height 2
Complete BT of
Height 3
Complete BT of Height 4
Must be filled (to be complete)
Optionally filled (to be complete)
10
Array-based Implementation
[1]
[2]
[3]
[4]
[5]
[6]
[0]
[7]
[8]
[9]
[10]
[11]
[12]
[13]
[14]
8
9
7
2
3
4
1
5
5 | 2 | 1 | 8 | 7 | 3 | 4 | 9 | … | … |
[0] | [1] | [2] | [3] | [4] | [5] | [6] | [7] | [8] | [9] |
Height 1
Height 2
Height 3
Height 4
11
Array-based Implementation
[1]
[2]
[3]
[4]
[5]
[6]
[0]
[7]
[8]
[9]
[10]
[11]
[12]
[13]
[14]
8
7
2
3
9
2
1
5
12
Array-based Implementation
5 | 2 | 1 | 8 | None | 3 | None | None | 7 | … |
[0] | [1] | [2] | [3] | [4] | [5] | [6] | [7] | [8] | [9] |
[1]
[2]
[3]
[4]
[5]
[6]
[0]
[7]
[8]
[9]
[10]
[11]
[12]
[13]
[14]
8
7
2
3
9
2
1
5
13
Reference-based Implementation
class TreeNode():
def __init__(self, x):
self.item = x
self.left = None
self.right = None
class BinaryTree():
def __init__(self, node):
self.root = node
14
Tree Traversal
r
TL
TR
r
TL
TR
r
TL
TR
Preorder
Root - Left - Right
2
1
3
Inorder
Left - Root - Right
Postorder
Left - Right - Root
1
2
3
1
3
2
15
Tree Traversal Example
60 {20 subtree} 70
60 20 10 {40 subtree} 70
60 20 10 40 30 50 70
{20 subtree} 60 70
10 20 {40 subtree} 60 70
10 20 30 40 50 60 70
{20 subtree} 70 60
10 {40 subtree} 20 70 60
10 30 50 40 20 70 60
60
20
70
10
40
30
50
16
Tree Traversal Implementation
def preorder(node):
if node is not None:
print(node.item)
preorder(node.left)
preorder(node.right)
preorder(root)
def inorder(node):
if node is not None:
inorder(node.left)
print(node.item)
inorder(node.right)
inorder(root)
17
Binary Search Tree
18
Definition of Binary Search Tree
r
TL
TR
<
<
19
Binary Search Tree Operations
20
Binary Search Tree Examples
Check! All these 3 BSTs contain the same data.
21
Search (Retrieval)
60
20
70
10
40
30
50
40
55
Found!
Not exists
22
Search (Retrieval): Implementation
Base case (empty BST): Not found!
General case: case 1, 2, 3
def search(root, key):
if root is None:
return None # Not found
elif key == root.item:
return root # Found
elif key < root.item:
return search(root.left, key)
else: # key > root.item
return search(root.right, key)
23
Search (Retrieval): Time Complexity
If the tree is balanced (close to full), the height gets closer to O(log N).
If the tree is unbalanced (close to linked list), the height gets closer to O(N).
Then, how the shape of a tree is determined? We will revisit this soon.
Length from the root to the leaf!
24
Insertion
60
20
70
10
40
30
50
55
55
25
Insertion: Implementation
Base case: Create new node
General case: 3 ways
def insert(root, item):
if root is None:
new_node = TreeNode(item)
return new_node
elif key == root.item:
# ERROR: already exists
elif key < root.item:
new_subtree = insert(root.left, item)
root.left = new_subtree
return root
else: # key > root.item
new_subtree = insert(root.right, item)
root.right = new_subtree
return root
26
Deletion
27
Deletion (Case 1)
60
20
70
10
40
30
50
80
35
28
Deletion (Case 2)
This slide is best seen with animations.
60
20
70
10
40
30
50
80
35
29
Deletion (Case 3)
This slide is best seen with animations.
Similarly, we may nominate the immediate predecessor (=right-most item in the left subtree.)
60
20
70
10
40
30
50
80
30
35
35
30
Deletion: Implementation
Locating the target
delete function returns the subtree to replace the target node to be deleted.
def delete(root, key):
if root is None:
return root
if key < root.key:
root.left = delete(root.left, key)
elif key > root.key:
root.right = delete(root.right, key)
else:
... (to be continued)
31
Deletion: Implementation
Case 3: both children
Case 1: no child if root.right is also None
Case 2: single child
After this line, we now delete the node im_su.
... (continuing)�
else:
if root.left is None:
new_root = root.right
root = None
return new_root
elif root.right is None:
new_root = root.left
root = None
return new_root
else:
im_su = get_immediate_successor(root)
root.key = im_su.key
root.right = delete(root.right, im_su.key)
return root
def get_immediate_successor(target):
curr = target.right
while curr.left is not None:
curr = curr.left
return curr
32
Revisiting the shape of BST
4
7
2
3
5
1
6
7
6
5
4
3
2
1
33
Balanced Trees
Red-black tree: guarantees that the height is lower than 2 log(N+1).
AVL tree: guarantees that heights of the two child subtrees of any node differ by at most 1.
34
Tree Sort
r
TL
TR
Inorder
Left - Root - Right
1
2
3
35
Time Complexity
= When the tree is significantly unbalanced.
When?
Task | Average-case | Worst-case |
Insertion | | |
Retrieval | | |
Deletion | | |
Traversal | | |
O(log N)
O(log N)
O(log N)
O(N)
O(N)
O(N)
O(N)
O(N)
36
Applications of Binary Search Trees
37
HW1
38
HW1
39
HW2
60
20
70
10
40
30
50
60
20
70
10
40
No
Yes
40
HW2
41
HW3
60
20
70
10
40
30
50
60
20
70
10
40
30
50
42
HW3
43
HW4
44
HW4
45
HW5
46
HW6
47
HW7
48