Proofs: k-d tree
These are the human proofs of k-d tree, at full length.
The k-d tree operations keep the order invariant and answer range and nearest queries exactly full
This proof shows: correctness, termination.
We use the names of the pseudocode on the page. For an axis , the order compares the superkeys lexicographically. It is a total order on , and implies . Write for the multiset of points in the subtree of .
Invariant. (A) A node at depth has axis . (K) At each node with axis , each has , and each has .
Lemma 1 (region). Let (K) hold. For each node , define , and , where . Then .
Proof. By induction on depth. The root is clear. A point of is in and has , so ; the right side is the same with .
BUILD. By induction on , BUILD returns a tree on exactly the multiset in which (A) and (K) hold with depths counted from . For , line L1 returns the empty tree. Otherwise line L3 picks . The set of line L5 holds the points , and the multiset of line L6 holds the points with one copy of removed; together with these are exactly , and both are smaller than , so the induction applies and the recursion stops. The node gets axis and its children get depth , so (A) holds. Each point of the left subtree is and each point of the right subtree is , so (K) holds at the new node, and below it by induction.
INSERT. Each pass of the loop of lines L14 to L16 moves one level down, so the loop stops after at most passes. The new node is a child of the last , with axis one more than the axis of modulo , so (A) holds. At each node on the path, the loop went left exactly when , so the new point is on the side of that (K) asks for. Nodes off the path do not change.
FIND-MIN. FIND-MIN returns a node whose point is least in over . By induction on the size: the candidates are and the minima of the subtrees it visits. The only subtree it skips is when , and then by (K) each point there is , so is at least as small. It stops since each call goes to a smaller subtree.
DELETE. If line L23 finds no node, nothing changes. Suppose the search reaches a node with point . Each pass of lines L24 and L25 replaces by the point of a node strictly below , and then works on ; line L26 removes a leaf. The depth of grows at each pass, so the loop stops after at most passes, and the multiset of points loses exactly one copy of : the point of is overwritten, each copied point leaves its old node at the next pass, and the last node is removed. (A) holds, since no node changes depth except in line L25, treated below.
We show (K) holds after each pass, at every node. Fix a pass at node with axis , and let be the node that FIND-MIN returns, with point .
- Line L24. is least in over , so every other point that stays in the right subtree is . Each point of the left subtree is the old point of , which is since came from the right subtree, so it is . So (K) holds at . For an ancestor of , moved from to , which are on the same side of , so the constraint of on is unchanged. The node still holds for now, and the next pass treats it.
- Line L25. Here is empty. is least in over , so every point that stays in that subtree is . The subtree moves to the right side of , at the same depth, so (A) holds, and (K) at asks exactly for . Inside the moved subtree nothing changed. Ancestors are as in line L24.
- Line L26. Removing a leaf keeps (K) everywhere.
During the passes the point is held by two nodes, and ; the next pass overwrites the point of , so at the end each point is held once and (K) holds at every node.
RANGE-SEARCH. Let . Every point reported is in by line L9, and each node is visited at most once, since the calls follow the tree, so no point is reported twice from one node. Suppose is the point of a node , and let be an ancestor of with axis . If is in the left subtree of , then by Lemma 1 , and , so the test of line L11 holds; if it is in the right subtree, , and the test of line L12 holds. So the search reaches , and line L9 reports . The search visits at most nodes and stops.
NEAREST. Let be the query and the value of the global bound. We show that at the end is a point of the tree at the least distance from . The value only goes down and is always the distance from to . Suppose a point at the least distance is never compared in line L18. Then some call skipped a subtree that holds it: line L22 at a node with axis decided not to search , with . The subtree is on the other side of from , or on that plane, so by Lemma 1, , and . Since is the distance of a point of the tree, , so , and is already a nearest point. If no skip hides , line L18 compares it and afterward. In both cases the final is at distance . The calls follow the tree, so they stop.