Week 4 - Binary Search Trees
Week 4 - Binary Search Trees
WARNING
A binary search tree is a binary tree storing keys (or key-value pairs)
satisfying the following BST property
6
Note that an inorder traversal
of a binary search tree visits the keys 2 9
in increasing order.
1 4 8
External nodes do not store items (and with careful coding, can be
omitted, using null to refer to such)
2 9
1 4 8
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
12
9 26
3 11 24 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
12
9 26
3 11 24 30
2 5 22 29 31
20
Tree T:
O(1)
h
O(1)
< 6
To perform operation put(k, o), we
search for key k (using search) 2 9
>
1 4 8
If k is found in the tree, replace the >
corresponding value by o
w
If k is not found, let w be the 6
external node reached by the
search. We replace w with an 2 9
internal node holding (k, o)
1 4 8
w
5
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
Search for 23
12
9 26
3 11 24 30
2 5 22 29 31
20 23
6
To perform operation remove(k),
w
we search for key k (using search) 2 9
to find the node w holding k
1 4 8
We distinguish between two cases
– w has one external child
– w has two internal children 6
w
If k is not in the tree we can either 2 9
throw an exception or do nothing 1 4 8
depending on the ADT specs
1 5 8
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
Search for 24
12
9 26
3 11 24 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
Remove z and w
12
9 26
3 11 24 30
2 5 22 z 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
12
9 26
3 11 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
12 Promote remaining
child to take spot of w
9 26
3 11 30
2 5 22 29 31
20
6 9
u
The University of Sydney © Goodrich, Tamassia, Goldwasser Page 17
Deletion algorithm
def remove(k)
w ← search(k, root)
if w.isExternal() then
# key not found
return null
else if w has at least one external child z then
remove z
promote the other child of w to take w’s place
remove w
else
# y is leftmost internal node in the right subtree of w
y ← immediate successor of w
replace contents of w with entry from y
remove y as above
This means that with this definition duplicate key values are not
allowed (as needed when implementing Map)
E.g., find all cars on eBay priced between 10K and 15K.
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
12
9 26
3 11 24 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
9 26
3 11 24 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
Is 12 in Q?
Q=[8,28] 12
Yes, so 12 will be
in the output and
9 26 we continue the
search in both
3 11 24 30 subtrees
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
Is 9 in Q?
Q=[8,28] 12
Yes, so 9 will be in
the output and we
9 26 continue the search
in both subtrees
3 11 24 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
Q=[8,28] Is 8>3?
12
Yes, continue search
in right subtree.
9 26
3 11 24 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
Q=[8,28] Is 8>5?
12
Yes, continue search
in right subtree.
9 26
3 11 24 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
9 26
3 11 24 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
Q=[8,28] Is 11 in Q?
12
Yes, return 11 and
continue the search in
9 26 both subtrees.
3 11 24 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
9 26
3 11 24 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
Q=[8,28] Is 26 in Q?
12
Yes, return 26 and
continue the search in
9 26 both subtrees.
3 11 24 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
Q=[8,28] Is 24 in Q?
12
Yes, return 24 and
continue the search in
9 26 both subtrees.
3 11 24 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
Q=[8,28] Is 22 in Q?
12
Yes, return 22 and
continue the search in
9 26 both subtrees.
3 11 24 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
Q=[8,28] Is 20 in Q?
12
Yes, return 20 and
continue the search in
9 26 both subtrees.
3 11 24 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
9 26
3 11 24 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
Q=[8,28] Is 30>28?
12
Yes, continue the
search in left subtree.
9 26
3 11 24 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
Q=[8,28] Is 29>28?
12
Yes, continue the
search in left subtree.
9 26
3 11 24 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
9 26
3 11 24 30
2 5 22 29 31
20
S={2,3,5,9,11,12,20,22,24,26,29,30,31}
Q=[8,28] 12
9 26
3 11 24 30
2 5 22 29 31
20
Therefore, since we only spend O(1) time per node we visit, the
total running time of range search is O(|output| + tree height)
n(1)
Height of an AVL Tree 4
z
17 78 17 78
y
32 50 88 32 50 88
48 62 48 62
x
54
before inserting 54 after initial insertion w
The University of Sydney Page 47
Re-establishing AVL property
T1
4
44
If tree does not have 2 3 x
17 62 z
AVL property, do a trinode y
1 2 2
78
restructure at x, y, z 32
1
50
1 1
48 54 88
It can be argued that tree T2
has AVL property after operation
T0 T1 T3
The University of Sydney Page 48
Augmenting BST with a height attribute
Thus, we can maintain the height only using O(h) work per insert
The University of Sydney Page 49
Improving Balance: Trinode Restructuring
Single rotation
a=z b=y
around b
b=y a=z c=x
T0
c=x
T1 T0 T1 T2 T3
T2 T3
b=x
a=z Double rotation
around c and b
a=z c=y
c=y
T0
b=x T0 T1 T2 T3
T3
T1 T2
The University of Sydney Page 51
Pseudo-code
Single Rotations:
a =z single rotation b =y
b =y a =z c=x
c=x
T0 T3
T1 T3 T0 T1 T2
T2
T3 T3
T0 T2 T2 T1 T0
T1
The University of Sydney Page 53
Trinode Restructuring (when done by Double Rotation)
Double rotations:
T0 T2
T2 T3 T0 T1 T3
T1
T0 T2
T3 T2 T3 T1 T0
T1
The University of Sydney Page 54
Performance
Assume we are given a reference to the node x where we are
performing a trinode restructure and that the binary search tree is
represented using nodes and pointers to parent, left and right children
y
17 62 w 17 62
x
32 50 78 50 78
48 54 88 48 54 88
62
z 44
44 78
w 17 62 y
17 50 88
50 78 x
48 54
48 54 88
isEmpty() true Ø
put(5,A) null (5,A)
put(7,B) null (5,A),(7,B)
put(2,C) null (5,A),(7,B),(2,C)
put(8,D) null (5,A),(7,B),(2,C),(8,D)
put(2,E) C (5,A),(7,B),(2,E),(8,D)
get(7) B (5,A),(7,B),(2,E),(8,D)
get(4) null (5,A),(7,B),(2,E),(8,D)
get(2) E (5,A),(7,B),(2,E),(8,D)
size() 4 (5,A),(7,B),(2,E),(8,D)
remove(5) A (7,B),(2,E),(8,D)
remove(2) E (7,B),(8,D)
get(2) null (7,B),(8,D)
isEmpty() false (7,B),(8,D)
firstEntry() returns the entry with smallest key; if map is empty, returns null
lastEntry() returns the entry with largest key; if map is empty, returns null
ceilingEntry(k) returns the entry with least key that is greater than or equal to
k (or null, if no such entry exists)
floorEntry(k) returns the entry with greatest key that is less than or equal to k
(or null, if no such entry exists)
lowerEntry(k) returns the entry with greatest key that is strictly less than k (or
null, if no such entry exists)
higherEntry(k) returns the entry with least key that is strictly greater than k (or
null, if no such entry exists)
subMap(k1,k2) returns an iteration of all the entries with key greater than or
equal to k1 and strictly less than k2
9 c 6 c 5 c 8 c
entries
The University of Sydney Page 63
Tree-Based (sorted) Map