Proofs: Quadtree
These are the human proofs of Quadtree, at full length.
The PR quadtree operations keep the compact invariant and answer window and nearest queries exactly full
This proof shows: correctness, termination.
We use the names of the pseudocode. The root cell is , cells are half-open squares, and points have integer coordinates. For a node let be the set of points stored in the leaves below . The invariant (Q) asks: (1) each point of the tree lies in the cell of its leaf and is stored once; (2) each leaf holds at most points; (3) each internal node has , and each leaf has ; and (4) the children of an internal node of side are its four quadrants, of side .
Lemma 1 (quadrants). For a cell of side , the four quadrants are disjoint, their union is , and the quadrant chosen for is the one that holds . Proof. On each axis, is the disjoint union of and , and the test picks the half that holds . The product of the halves on the two axes gives the claim.
Lemma 2 (unit cells). A cell of side 1 holds at most one integer point. Proof. It is with integers , and the only integer point in it is .
Search. By Lemma 1 and (Q) part 4, at each internal node the point lies in exactly one child cell, so exactly one leaf has a cell that holds , and line L1 (and line L12) reaches it in at most steps, since the side halves at each step. By (Q) part 1, is stored exactly when it is in that leaf's list.
INSERT. Let be a point of the root cell that is not stored. Lines L1 to L3 add to the only leaf whose cell holds it, and add 1 to the count of each node whose subtree now holds , so parts 1 and 3 hold. If , the loop does not run and (Q) holds.
Otherwise the loop starts with a leaf that holds points, all in its cell, while (Q) holds at every other node. By Lemma 2, the side of is at least 2, so line L5 can make the four quadrants. Line L6 moves each point into the quadrant that holds it (Lemma 1), with counts equal to the list sizes; now is internal with , so parts 3 and 4 hold at . The children's lists add up to points, so at most one child holds more than . If none does, (Q) holds everywhere and the loop stops. If one does, it holds exactly points, all in its cell, and the loop continues with it in the same situation. The side halves at each pass and is at least 2 at each pass, so after at most passes the loop stops.
DELETE. Let be stored, let be its leaf, and let be the path from the root down to the parent of . After line L13, is gone and the counts of and of each are one less, so all counts are correct and parts 1, 2 and 4 hold. Part 3 can fail only at the nodes , and only when now.
Line L14 treats in turn. Claim: when it reaches , (Q) holds at every node except possibly , and all counts are correct. This holds for . If , then for each , because the count of a node is at least the count of each child, so (Q) holds everywhere and the loop may stop. If , each child of has ; by the claim, part 3 holds at , so is a leaf. Line L14 gathers the lists of the four leaves, at most points in total, all in the cell of by part 1 and Lemma 1, into one leaf with the same count. Parts 1 to 4 then hold at , and the claim holds for . The loop makes at most steps.
Uniqueness. Let be a tree on a set of points of the cell that satisfies (Q). If , part 3 forces a leaf with list . If , part 3 forces an internal root, part 4 fixes its children as the quadrants , and by part 1 and Lemma 1 the child for is a tree on that satisfies (Q). By induction on the side, it is unique. So the shape depends only on .
RANGE-SEARCH. Let . Each reported point is stored and is in by the test of line L10, and the calls follow the tree, so each leaf is reached at most once, and by part 1 no point is reported twice. Let , with leaf . For each node on the path from the root to , the cells along the path are nested, so lies in the cell of and in ; the cell of meets , and line L9 does not stop the search at . Line L11 calls every child, so the search reaches , and line L10 reports . The calls follow a finite tree, so the search stops.
NEAREST. Write . For each point below , is in the cell of , so . For a child of , the cell of is inside the cell of , so . Hence the keys extracted at line L18 never decrease: a key inserted at line L21 is at least the key just extracted, and the queue returns the smallest key.
Let be a stored point closest to , and suppose the loop ends with farther than , or with = none. The tree is not empty, so the root has count at least 1. Call a node processed when it was extracted and passed the test of line L19. The root is inserted at line L16, and each processed internal node inserts all its children with a nonzero count. Let be the deepest node on the path from the root to the leaf of that was inserted into the queue. If was processed and is a leaf, line L20 compared with , and is at least as close as from then on, a contradiction. If was processed and is internal, its child on the path to has a nonzero count and was inserted, against the choice of . So was never processed. The loop then ended at line L19 with an extracted key , while was in the queue or was the node just extracted. Since was the smallest key, , a contradiction. If = none at the end, the loop stopped because the queue was empty, so was processed, and the cases above apply. Hence NEAREST returns a closest stored point. Each node is inserted at most once, so the loop stops.