Algorithm Search⌘K

Proofs: AA tree

These are the human proofs of AA tree, at full length.

AA tree insertion and deletion keep the level rules full

This proof shows: correctness.

Write ℓ(x)\ell(x) for the level of xx, with ℓ(nil)=0\ell(\text{nil}) = 0. A subtree is valid when it is a binary search tree and every node tt satisfies

  • (A2) ℓ(t.left)=ℓ(t)−1\ell(t.left) = \ell(t) - 1,
  • (A3) ℓ(t.right)∈{ℓ(t),ℓ(t)−1}\ell(t.right) \in \{\ell(t), \ell(t) - 1\},
  • (A4) ℓ(t.right.right)<ℓ(t)\ell(t.right.right) < \ell(t) when t.right≠nilt.right \ne \text{nil}.

The rules (A1), a leaf has level 1, and (A5), a node above level 1 has two children, follow: a leaf has ℓ(t.left)=0\ell(t.left) = 0, so ℓ(t)=1\ell(t) = 1 by (A2); and if ℓ(t)≥2\ell(t) \ge 2, both children have level at least 1 by (A2) and (A3), so they are not nil. A link from tt to a child of the same level is horizontal; (A2) forbids horizontal left links, and (A4) forbids two horizontal right links in a row. Lines L1 to L5 are SKEW and SPLIT; a rotation keeps the in-order sequence, so the search order is never at risk, and the proofs below only check levels. "No-op" means that SKEW or SPLIT finds its test false and returns its argument. On a valid subtree, both are no-ops, since their tests are exactly the negations of (A2) and (A4) at the root.

Insertion

Lemma 1. Let tt be valid with ℓ(t)=P\ell(t) = P (with P=0P = 0 when tt is nil), and let kk be absent. INSERT(t,k)(t, k) returns a valid subtree t′t' with the keys of tt and kk, and ℓ(t′)∈{P,P+1}\ell(t') \in \{P, P + 1\}. If ℓ(t′)=P+1\ell(t') = P + 1, then both children of t′t' have level PP, and tt is nil or has a right child of level PP.

Proof. By induction on the height. If tt is nil, line L6 returns a leaf of level 1=P+11 = P + 1 whose children have level 0=P0 = P.

Let tt be a node, with a=t.lefta = t.left of level P−1P - 1 and b=t.rightb = t.right.

Left case (line L7 goes left), with a′a' the result. By induction ℓ(a′)∈{P−1,P}\ell(a') \in \{P - 1, P\}. If ℓ(a′)=P−1\ell(a') = P - 1, the rules at tt are as before, SKEW and SPLIT are no-ops, and tt is returned at level PP. If ℓ(a′)=P\ell(a') = P, both children of a′a' have level P−1P - 1, and SKEW rotates: a′a' becomes the top, its right child is tt, and t.leftt.left becomes the old a′.righta'.right, of level P−1P - 1. Now tt is valid at level PP, and a′a' has a left child of level P−1P - 1 and the horizontal right child tt. If ℓ(b)=P−1\ell(b) = P - 1, (A4) holds at a′a', SPLIT is a no-op, and the result has level PP. If ℓ(b)=P\ell(b) = P, SPLIT rotates left at a′a': tt becomes the top at level P+1P + 1, with left child a′a' and right child bb, both of level PP. The node a′a' now has two children of level P−1P - 1, and (A4) at tt holds because ℓ(b.right)<P\ell(b.right) < P by the old (A4) at tt. This is the case ℓ(t′)=P+1\ell(t') = P + 1, and tt had the right child bb of level PP.

Right case, with b′b' the result. If ℓ(b)=P−1\ell(b) = P - 1, then by induction ℓ(b′)∈{P−1,P}\ell(b') \in \{P - 1, P\}, and if ℓ(b′)=P\ell(b') = P, its right child has level P−1P - 1. Either way (A3) and (A4) hold at tt, SKEW and SPLIT are no-ops, and the result has level PP. If ℓ(b)=P\ell(b) = P, then bb is a node whose right child has level less than PP by (A4) at tt, so bb has no right child of level PP, and by induction ℓ(b′)=P\ell(b') = P. (A3) holds. If ℓ(b′.right)<P\ell(b'.right) < P, (A4) holds and tt is returned at level PP. If ℓ(b′.right)=P\ell(b'.right) = P, SPLIT rotates left at tt: b′b' becomes the top at level P+1P + 1, with left child tt and right child b′.rightb'.right, both of level PP. The node tt has the children aa and the old b′.leftb'.left, both of level P−1P - 1, and (A4) holds at b′b' because b′.rightb'.right is valid. This is the case ℓ(t′)=P+1\ell(t') = P + 1, and tt had the right child bb of level PP. SKEW at line L8 is a no-op in the right case, because t.leftt.left did not change. □\square

Deletion

Lemma 2. Let tt be valid with ℓ(t)=P≥1\ell(t) = P \ge 1, and let kk be a key of tt. DELETE(t,k)(t, k) returns a valid subtree t′t' with the keys of tt without kk, and

  1. (a) ℓ(t′)∈{P−1,P}\ell(t') \in \{P - 1, P\};
  2. (b) if tt has no right child of level PP and ℓ(t′)=P\ell(t') = P, then t′t' has no right child of level PP;
  3. (c) if tt has a right child of level PP, then ℓ(t′)=P\ell(t') = P.

Proof. By induction on the height. If tt is a leaf holding kk, line L10 returns nil, of level 0=P−10 = P - 1; (b) and (c) hold since tt has no right child. Otherwise lines L9, L11 or L12 replace one child of tt by the result of a recursive call on it, and maybe replace t.keyt.key by the least key ss of t.rightt.right or the largest key pp of t.leftt.left, which is then deleted from that child. In each case the keys are those of tt without kk, and the search order holds: ss is less than all other keys of t.rightt.right and greater than the keys of t.leftt.left, and symmetrically for pp. At line L11, t.leftt.left is nil, so P=1P = 1, and t.rightt.right is a node of level 1. Let a=t.lefta = t.left, of level P−1P - 1, and b=t.rightb = t.right, of level P−1P - 1 or PP.

Case L1: the left child, ℓ(a′)=P−1\ell(a') = P - 1. DECREASE-LEVEL computes min⁡(P−1,ℓ(b))+1=P\min(P - 1, \ell(b)) + 1 = P and changes nothing. All rules at tt hold as before, and lines L14 and L15 are no-ops: SKEW at tt because ℓ(a′)≠P\ell(a') \ne P, and SKEW and SPLIT at the right side because those subtrees are unchanged and valid, and SPLIT at tt because (A4) holds at tt. The result is tt at level PP with the same right child, so (b) and (c) hold.

Case L2: the left child, ℓ(a′)=P−2\ell(a') = P - 2. Lines L16 and L17 set ℓ(t)=P−1\ell(t) = P - 1, and lower bb to P−1P - 1 if it was at PP.

L2a: ℓ(b)=P−1\ell(b) = P - 1 before. The children of bb have levels P−2P - 2 and P−2P - 2 or P−1P - 1. The three SKEWs are no-ops: a′a' and b.leftb.left are one level below their parents, and b.rightb.right is valid. If ℓ(b.right)=P−2\ell(b.right) = P - 2, SPLIT is a no-op and tt is returned at level P−1P - 1: its children have levels P−2P - 2 and P−1P - 1, and (A4) holds. If ℓ(b.right)=P−1\ell(b.right) = P - 1, SPLIT rotates left at tt: bb becomes the top at level PP with left child tt and right child b.rightb.right of level P−1P - 1. The node tt, at level P−1P - 1, has children a′a' and the old b.leftb.left, both of level P−2P - 2. (A4) at bb holds since ℓ(b.right.right)≤P−1\ell(b.right.right) \le P - 1. The second SPLIT, at b.rightb.right, is a no-op. The result has level PP and no right child of level PP, as (b) needs.

L2b: ℓ(b)=P\ell(b) = P before. By (A4) at tt and (A3) at bb, both children of bb had level P−1P - 1; call them x=b.leftx = b.left and y=b.righty = b.right. After line L17, tt, bb, xx and yy all have level P−1P - 1. The node xx has a left child of level P−2P - 2 and a right child zz of level P−2P - 2 or P−1P - 1; if ℓ(z)=P−1\ell(z) = P - 1, then by (A4) at xx the children of zz have level P−2P - 2. The first SKEW, at tt, is a no-op. The second, at bb, rotates right: xx takes the place of bb, and bb becomes the right child of xx with left child zz. The third, at bb again: if ℓ(z)=P−1\ell(z) = P - 1, it rotates right, so zz is the right child of xx, and bb the right child of zz with a left child of level P−2P - 2. Now the right spine from tt is t,x,(z,) b,yt, x, (z,)\ b, y, all at level P−1P - 1, and each of them has a left child of level P−2P - 2; after yy comes y.righty.right, of level P−2P - 2 or P−1P - 1.

The SPLIT at tt rotates left, because t.right.rightt.right.right (the node zz or bb) has level P−1P - 1: xx becomes the top at level PP, with left child tt, which now has two children of level P−2P - 2. The SPLIT at x.rightx.right then acts on the node ww after xx.

  • If w=zw = z: z.right=bz.right = b and b.right=yb.right = y have level P−1P - 1, so it rotates left and bb rises to level PP, with children zz and yy of level P−1P - 1. The node zz has two children of level P−2P - 2. (A4) at xx holds since ℓ(y)=P−1\ell(y) = P - 1, and (A4) at bb holds since ℓ(y.right)≤P−1\ell(y.right) \le P - 1.
  • If w=bw = b and ℓ(y.right)=P−1\ell(y.right) = P - 1: it rotates left, and yy rises to level PP, with children bb (whose children have level P−2P - 2) and y.righty.right of level P−1P - 1. (A4) holds at xx, since ℓ(y.right)<P\ell(y.right) < P, and at yy, since y.righty.right is valid.
  • If w=bw = b and ℓ(y.right)=P−2\ell(y.right) = P - 2: it is a no-op. The node bb has children of levels P−2P - 2 and P−1P - 1, and (A4) at bb holds; (A4) at xx holds since ℓ(y)=P−1\ell(y) = P - 1.

In all three cases the result is valid at level PP, as (c) needs.

Case R1: the right child, ℓ(b)=P\ell(b) = P before. By (A4) at tt, bb has no right child of level PP. By induction ℓ(b′)∈{P−1,P}\ell(b') \in \{P - 1, P\}, and if ℓ(b′)=P\ell(b') = P, by (b) b′b' has no right child of level PP. DECREASE-LEVEL computes min⁡(P−1,ℓ(b′))+1=P\min(P - 1, \ell(b')) + 1 = P and changes nothing. (A3) and (A4) hold at tt, all SKEWs and SPLITs are no-ops, and tt is returned at level PP, as (c) needs.

Case R2: the right child, ℓ(b)=P−1\ell(b) = P - 1 before, ℓ(b′)=P−1\ell(b') = P - 1. As in case L1, nothing changes at tt, (A4) holds because ℓ(b′.right)≤P−1\ell(b'.right) \le P - 1, and tt is returned at level PP with a right child of level P−1P - 1, as (b) needs.

Case R3: the right child, ℓ(b)=P−1\ell(b) = P - 1 before, ℓ(b′)=P−2\ell(b') = P - 2. DECREASE-LEVEL sets ℓ(t)=P−1\ell(t) = P - 1; b′b' is lower and does not change. Now aa, of level P−1P - 1, is a horizontal left child. Its children have level P−2P - 2 and, for u=a.rightu = a.right, P−2P - 2 or P−1P - 1; if ℓ(u)=P−1\ell(u) = P - 1, the children of uu have level P−2P - 2 by (A4) at aa. The first SKEW rotates right at tt: aa is the top, with right child tt, and t.left=ut.left = u.

  • If ℓ(u)=P−2\ell(u) = P - 2: the second and third SKEWs are no-ops (uu is one below tt, and b′b' is valid), and SPLIT at aa is a no-op since ℓ(b′)=P−2\ell(b') = P - 2. The result is aa at level P−1P - 1, with children of levels P−2P - 2 and P−1P - 1; tt has two children of level P−2P - 2.
  • If ℓ(u)=P−1\ell(u) = P - 1: the second SKEW rotates right at tt, so the right spine is a,u,ta, u, t at level P−1P - 1, and tt has children of level P−2P - 2. The third SKEW, at tt, is a no-op. SPLIT at aa rotates left: uu rises to level PP, with left child aa (children of level P−2P - 2) and right child tt of level P−1P - 1. (A4) at uu holds since ℓ(b′)=P−2\ell(b') = P - 2, and SPLIT at tt is a no-op. The result has level PP and no right child of level PP, as (b) needs.

These are all cases. □\square

Conclusion

Theorem. Starting from the empty tree, after any sequence of insertions and deletions the tree is a valid AA tree with exactly the keys inserted and not deleted since, and its height is at most 2lg⁡(n+1)2 \lg(n + 1).

Proof. The class methods search first, so INSERT gets an absent key and DELETE a present one; Lemmas 1 and 2 at the root give a valid tree with the right keys. For the height: a node of level ℓ\ell has at least 2ℓ−12^\ell - 1 nodes in its subtree, by induction, because its two children have level at least ℓ−1\ell - 1 by (A2) and (A3). On a downward path, a left step lowers the level by one, and of two right steps in a row at least one lowers it, by (A4). So a path from the root, of level LL, has at most 2L2L nodes, and n≥2L−1n \ge 2^L - 1 gives h≤2L≤2lg⁡(n+1)h \le 2L \le 2 \lg(n + 1). ■\blacksquare

Back to AA tree