Overview:
Review BST Remove
Segment Intersection Project
Balanced Trees: AVL Trees
remove
method of BinarySearchTree
Book 4.3.4.
o o
| |
z=o A
\ ==>
A
o o
| |
z=o A
/ ==>
A
|
z=o
/ \
A B
The main idea is to replace z with the node after z, which is the first node y in subtree B. We then recursively delete y from B.
Solution for remove()
(similar to book Figure 4.25):
public void remove(K key) {
root = remove_helper(root, key);
}
private Node remove_helper(Node<K> curr, K key) {
if (curr == null) {
return null;
} else if (lessThan.test(key, curr.data)) { // remove in left subtree
curr.left = remove_helper(curr.left, key);
return curr;
} else if (lessThan.test(curr.data, key)) { // remove in right subtree
curr.right = remove_helper(curr.right, key);
return curr;
} else { // remove this node
if (curr.left == null) {
return curr.right;
} else if (curr.right == null) {
return curr.left;
} else { // two children, replace with first of right subtree
Node<K> min = curr.right.first();
curr.data = min.data;
curr.right = remove_helper(curr.right, min.data);
return curr;
}
}
}
What is the time complexity? $O(h)$, where $h$ is the height.
Given a set of n segments, are their any pairs that intersect?
Suppose we have a routine for testing whether 2 segments intersect.
Simplifications:
Brute force: test all combinations O(n²)
A better algorithm: Line Sweep
We’ll need fast membership testing, insert, remove, and next/previous.
Recall that search time is O(h), where h is the height of the tree.
Definition of height
int compute_height(Node n) {
if (n == null) {
return -1;
} else {
int hl = compute_height(n.left);
int hr = compute_height(n.right);
return 1 + Math.max(hl, hr);
}
}
Example tree with heights in brackets:
41[3]
/ \
20[2] 65[1]
/ \ /
11[0] 29[1] 50[0]
/
26[0]
The problem of unbalanced trees
o
\
o
\
o
\
o
\
o
\
o
\
o
height = n
vs.
o
/ \
/ \
o o
/ \ / \
o o o o
height = log(n)
Definition A tree is balanced if its height is O(log n) where n is the number of nodes in the tree.
Equivalently, the number of nodes is Ω(2ʰ) where h is the height.
Definition The AVL Invariant: the height of two child subtrees may only differ by 1, for every node in the tree.
Examples of trees that are AVL:
o o o o
/ / \ / \ / \
o o o o o o o
/ / \
o o o
Examples of trees that are not AVL:
o o o
/ \ / \
o o o o
\ \ / \
o o o o
\
o
Red-black trees are an alternative: AVL is faster on lookup than red-black trees but slower on insertion and removal because AVL is more rigidly balanced.
Let N(h) represent the minimum number of nodes in an AVL tree of height h. (The least-balanced possible scenario.)
N(h) = N(h-1) + N(h-2) + 1
We want to show that
h ≲ log₂ N(h)
To simplify, we have
N(h-2) + N(h-2) + 1 < N(h-1) + N(h-2) + 1 = N(h)
2·N(h-2) + 1 < N(h)
2·N(h-2) < N(h)
= 2·2·N(h-4)
= 2·2·2·N(h-6)
...
= 2^(h/2) < N(h)
Take the log of both sides
log₂ 2^(h/2) < log₂ N(h)
(log₂ Aᴮ = B log₂ A)
h/2 · log₂ 2 < log₂ N(h)
(log₂ 2 = 1, i.e. 2¹ = 2)
h/2 · 1 < log₂ N(h)
(multiply both side by 2)
h < 2 · log₂ N(h)
so we have
h ≲ log₂ N(h)