Proofs: Skew heap
These are the human proofs of Skew heap, at full length.
Skew heap operations take O(log n) amortized time full
This proof shows: time.amortized.
We prove that each merge of a top-down skew heap costs at most amortized units, where and are the sizes of its inputs. This is for insert, delete-min and meld. The argument is Sleator and Tarjan's.
Cost. The actual cost of a merge is the number of calls of MERGE that reach line L2, which is the number of nodes on the merge path: the nodes whose children are swapped. All other work is per call or per operation.
Potential. For a node , let be the number of nodes in its subtree. Call heavy if , and light otherwise, with . Let be the number of heavy nodes in all heaps. Then , and when there are no nodes.
Lemma 1. On the right path of a tree with nodes, at most nodes are light.
Proof. If is light, then and , so . Along the right path, sizes never grow, and they fall below half at each light node. If the light nodes are from the top, then , so and when is not a power of 2, or when it is. In both cases .
Lemma 2. In one merge, every heavy node on the merge path becomes light, and no node off the merge path changes its type.
Proof. The merge path consists of nodes of the right paths of the two inputs. A node off the merge path keeps both of its subtrees as they were, because MERGE only changes the fields of the nodes on its path, and returns other subtrees unchanged. So its type does not change.
Let be on the merge path, with old subtrees (left) and (right). After the merge, its right subtree is and its left subtree is the result of merging with another tree, which has at least nodes. If was heavy, then , so now , and is light.
Theorem. A merge of heaps with and nodes has amortized cost at most , with read as when a heap is empty.
Proof. Let the merge path have heavy and light nodes, measured before the merge. The actual cost is . By Lemma 2, the heavy nodes become light, at most the light nodes become heavy, and no other node changes, so . The amortized cost is at most . The merge path is part of the right paths of the two inputs, so by Lemma 1, .
The operations. Insert merges with a one-node heap, so its amortized cost is at most . Delete-min removes the root; this can only remove a heavy node, and the subtrees of all other nodes are unchanged, so does not grow. It then merges two heaps of total size , at amortized cost at most . Meld of heaps of sizes and costs at most .
Since starts at and is never negative, the actual cost of any sequence of operations starting from empty heaps is at most the sum of the amortized costs, which is for the largest heap size.
Skew merge keeps heap order and the keys full
This proof shows: correctness.
A tree is in heap order if the key of each node is at least the key of its parent. Write for the multiset of keys of .
Lemma. If and are heap-ordered trees with roots and , possibly empty, then returns the root of a heap-ordered tree with .
Proof. By induction on the total number of nodes . If or is NIL, line L1 returns the other tree, and the claim holds. Otherwise, after line L2, , and is at most every key of , by heap order and induction on depth. So is a smallest key of .
Let be the old right subtree of and the old left subtree. Line L4 makes the right subtree of . The call at line L5 has fewer nodes in total, because is not in or , so by induction it returns a heap-ordered tree with , which becomes the left subtree of .
The tree with root , left subtree and right subtree is in heap order: and are heap-ordered, every key of and of is at least by heap order of , and every key of is at least . Its keys are .
Theorem. INSERT, DELETE-MIN and MELD keep heap order and the correct multiset, and DELETE-MIN returns a smallest key.
Proof. A one-node tree is heap-ordered, so line L7 is correct by the lemma. In DELETE-MIN, the root holds a smallest key by heap order. Its two subtrees are heap-ordered and hold all other keys, so line L8 gives a heap-ordered tree of those keys by the lemma. Meld is one MERGE. The loop form in the implementation performs the same steps as the recursion: at each node of the merge path it moves the old left subtree to the right and continues the merge in the left field, and when the old right subtree is empty, MERGE(NIL, ) returns unchanged.