Maintaining AVL Property
What happens if we add(11)
?
Setup: tree nodes
private class Node<E> {
Node<E> parent;
Node<E> left;
Node<E> right;
E value;
}
Tree stores Node<E> root
Goal. Print the elements stored in tree in sorted order.
Define printDescendants(Node<E> nd)
method
void printDescendant(Node nd) {
if (nd.left != null)
printDescendants(nd.left);
print(nd.value)
if (nd.right != null)
printDescendants(nd.right);
}
void printDescendant(Node nd) {
if (nd.left != null) printDescendants(nd.left);
print(nd.value)
if (nd.right != null) printDescendants(nd.right);
}
Use recursive strategy to compute height of a node/tree!
Implement a sorted set (SimpleSSet
) with efficient operations:
find
add
remove
Previous best: sorted array with binary search
find
in $O(\log n)$ timeadd
/remove
in $O(n)$ timeIntroduced AVL trees
$T$ has AVL property if for every node $v$ with children $u$ and $w$, we have
$\vert h(u) - h(w) \vert \leq 1$
We showed:
add
/remove
/find
take $O(\log n)$ timeBut:
add
/remove
as previously implemented may destroy AVL propertyadd
/remove
as beforeWhat happens if we add(11)
?
If we add
a new node as before, it is always a leaf.
Which nodes could become unbalanced?
How can we check for unbalance?
All this takes $O(\log n)$ time if $T$ is AVL tree (before add
)
add
Suppose $T$ becomes unbalanced after add
Note: 4 possibilities of relative order of $x, y, z$
So: restructure tree to move $x$ up
Suppose $z$ became unbalanced after add(w)
What is root’s height after restructuring?
Why does restructuring restore balance of subtree?
Why does restructuring maintain BST property?
Does restructuring make tree balanced?
After add(w)
, iterate over $w$’s ancestors from $w$ upwards:
What is running time?
How do we remove
nodes?
Case 1: Leaf
Case 2: Single-child
Case 3: Two-child
Which cases modify tree structure?
$x, y, z$ redefined; same restructuring
What is height of root after restructuring?
Restructuring may again cause imblance! Must continue upwards.
After remove(w)
, iterate over removed node’s ancestors upwards:
What is running time?
We can modify add
/remove
such that
So
add
/remove
/find
operations happen in $O(\log n)$ time!Another Tree Representation:
Goal. Implement a priority queue with $O(\log n)$-time operations
Exercise. How could this goal be achieved with an AVL tree?