Proofs: Finger search tree
These are the human proofs of Finger search tree, at full length.
Finger search takes O(log d) time and updates at a finger take O(1) amortized rebalancing full
This proof shows: complexity, amortized.
Size measure. For a non-root node , let be its number of children if is internal, and its number of keys plus 1 if is a bottom node. By (F1) of the correctness proof, in a valid tree. During an update, one node at a time can reach (overfull, before its split) or (underfull, before a share or merge).
Lemma 1 (subtree size). A node at height (bottom nodes have height 0) has at least keys below it, unless it is a bottom root.
Proof. A non-root bottom node has at least 1 key, and an internal node has at least 2 children. Induction on .
So the height is at most .
Theorem 1 (finger search). Let be the number of keys strictly between the range of the finger and , that is, the keys in if and in if , and if holds . Then the climb of lines L1 to L5 goes up at most levels if , and no levels if ; FINGER-SEARCH takes time.
Proof. Take ; the other case is the mirror image. Suppose line L5 moves from a node at height to its parent. Then does not hold and, as is an ancestor of , , and by Lemma 1 of the correctness proof (the ranges at one level are in order and is below ). The neighbour exists, since the last node of a level has range ending at , and while does not hold , so . Every key below lies in , and there are at least of them by Lemma 1. So . If the climb reaches height , it left height , so and . If , no move up happens. The descent from height takes rounds. Each round of the climb and of the descent looks at nodes of at most 4 children, so the time is .
Theorem 2 (rebalancing). Starting from any valid tree, a sequence of inserts and deletes, each given the bottom node found by the finger search, does at most splits, merges and shares in total, plus 1 per increase of the height.
Proof. Let , , , , , and over the non-root nodes . always. The changes of when grows by 1 are (from ), and when drops by 1 they are (from ).
- A key enters or leaves a bottom node: changes by 1, so grows by at most 2.
- A split of a node with gives two nodes with and (internal) or and (bottom): drops by at least . The parent gains a child, which adds at most 2. So each split lowers by at least 1, except a split of the root, where the two halves become non-root nodes and add at most 1 to ; this happens once per increase of the height.
- A merge of a node with and a sibling with gives one node with (internal: children) or (bottom: keys): drops by at least . The parent loses a child, which adds at most 1. So each merge lowers by at least 1. When the root loses its last but one child, the child becomes the root and leaves the sum, which does not increase .
- A share happens at most once per delete, since it ends the delete. The node with goes to (drop 1) and the sibling drops from by 1 (change at most ), so does not increase.
So each update raises by at most 2 at its start and at most 2 at its last step, and each split or merge in between lowers it by at least 1, except root splits. Summing over the sequence, the number of splits and merges is at most , and for the non-root nodes of the initial tree; from an empty tree . Each split, merge or share takes time, including the change of the level links and of the ranges.
Corollary. An insert or a delete at a finger takes time for the finger search plus amortized time for the rebalancing. In particular, building the tree from sorted keys, each inserted from the finger of the previous one, takes time: the finger search has each time, and the root splits number at most .
Finger search and updates in a level-linked (2,4)-tree are correct full
This proof shows: correctness, invariant, termination.
Write for the range of node , with and allowed. The invariant has three parts.
- (F1) Shape. All bottom nodes are at the same depth. A non-root bottom node has 1 to 3 keys; an internal node has 2 to 4 children and one separator fewer; the root may be a bottom node with 0 to 3 keys.
- (F2) Ranges. The root has range . An internal node with children and separators has and , where and . The keys of a bottom node are increasing and lie in its range.
- (F3) Levels. For each depth, and link the nodes of that depth in left-to-right order.
Lemma 1. Under (F1) to (F3), the ranges of the nodes of one depth are disjoint and their union is , and the left-to-right order of the nodes is the order of their ranges. The range of a node contains the ranges of its descendants.
Proof. By induction on the depth. At depth 0 it is the root. If it holds at depth , (F2) splits each range at depth into the ranges of the children, in order, so it holds at depth .
Lemma 2 (DESCEND). If , DESCEND returns the bottom node below whose range holds .
Proof. Line L8 picks the least with (with , so exists). Then : for because , and for by the choice of . So holds in its range, and the loop keeps the condition. The depth grows each round, so the loop ends at a bottom node, and by Lemma 1 it is the only bottom node whose range holds .
Lemma 3 (FINGER-SEARCH). FINGER-SEARCH ends and returns the bottom node whose range holds .
Proof. Each round of lines L2 to L5 either stops (line L4 or the test of line L2) at a node whose range holds , or moves to the parent. The root's range holds , so the climb ends after at most the height of the tree. Then Lemma 2 applies.
So a search reports present exactly when is a key of the returned bottom node, because by (F2) and Lemma 1, a key can only be in the bottom node whose range holds it.
Insert. If is already in , nothing changes. Else line L12 puts into in sorted order, and lies in the range of by Lemma 3, so (F2) holds. Only the size condition of (F1) can fail, and only at . Line L15 splits :
- a bottom node with keys becomes and , with ; the ranges and hold the keys;
- an internal node with children and separators becomes with and , and with and , with ; the children keep their ranges, which satisfy (F2) in and , since and .
Linking just after keeps (F3). Line L17 puts after in the parent with between them, so the parent's separators become around and , which is (F2) for the parent; they stay increasing because . The parent has one more child and may now be overfull, which the next round handles. A split of the root (line L16) makes a new root with range and children , , one level higher; all bottom nodes stay at one depth. Each round goes one level up, so the loop ends. Line L19 returns the half of the split bottom node that holds .
Delete. If is not in , nothing changes. Else removing keeps (F2) at . Only the minimum size can fail, at a non-root node with parent and adjacent sibling ; say is left of (the other case is the mirror image), with separator between them in , so .
- Share, bottom. The largest key of moves into ; the new separator is $t' = $ the new largest key of , with . The keys of are , and the keys of , now and the old ones, are , since was the largest key of and the old keys of are . So (F2) holds.
- Share, internal. The last child of , with range , where is the last separator of , becomes the first child of ; moves down as the first separator of , and goes up into in the place of , with . Each child keeps its range, and the ranges match the new separators. (F3) does not change: stays at its place in its level.
- Merge. joins : the keys (bottom) or the children with between the two lists of separators (internal) go into , with $w.hi = $ old ; leaves ; is unlinked from its level. The ranges of the children do not change and match the new separators of , the keys of lie in its old range, which is now part of the range of , and the level order of the other nodes stays. The parent has one child fewer and may now be underfull, which the next round handles.
The sizes after a share or merge are in the bounds of (F1), because a share takes from a sibling above the minimum, and a merge joins a node below the minimum with a sibling at the minimum (0 + 1 keys or 1 + 2 children). If the root is left with one child, its range is the root's range by (F2), so making it the root keeps (F2), and all bottom nodes stay at one depth. Each round goes one level up, so the loop ends. The bottom node returned is or the node merged into; in both cases its range contains the old range of , which holds .