Algorithm Search⌘K

Proofs: R-tree

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

The R-tree operations keep the invariant, and search reports exactly the rectangles that meet the query full

This proof shows: correctness, termination.

We use the names of the pseudocode. A rectangle is closed. For a node uu let Obj⁡(u)\operatorname{Obj}(u) be the set of leaf entries in the subtree of uu. The invariant (R) says: (1) all leaves are at one depth; (2) each non-root node has between mm and MM entries, and an internal root has between 2 and MM; (3) the rectangle of each internal entry (r,c)(r, c) is MBR⁡(c)\operatorname{MBR}(c).

Lemma 1 (containment). Under (R) part 3, for each internal entry (r,c)(r, c) and each leaf entry (s,id)(s, id) in Obj⁡(c)\operatorname{Obj}(c), s⊆rs \subseteq r. Proof. By induction on the height of cc. If cc is a leaf, ss is the rectangle of an entry of cc, and MBR⁡(c)\operatorname{MBR}(c) contains it. If cc is internal, (s,id)(s, id) is below some entry (r′,c′)(r', c') of cc; by induction s⊆r′s \subseteq r', and r′⊆MBR⁡(c)=rr' \subseteq \operatorname{MBR}(c) = r. □\square

SEARCH. Each reported entry is a leaf entry whose rectangle meets qq (lines L1 and L2). Each node is reached by one path from the root, so no entry is reported twice. Conversely, let (s,id)(s, id) be stored with s∩q≠∅s \cap q \ne \emptyset, and let (r1,c1),…,(rh,ch)(r_1, c_1), \ldots, (r_h, c_h) be the internal entries on the path from the root to its leaf. By Lemma 1, s⊆ris \subseteq r_i, so ri∩q⊇s∩q≠∅r_i \cap q \supseteq s \cap q \ne \emptyset for each ii. By induction on ii, line L3 enters cic_i: the root is reached, and if the node holding (ri,ci)(r_i, c_i) is reached, the test of line L1 passes. In the leaf, line L1 passes for (s,id)(s, id) and line L2 reports it. The tree is finite and each node is entered once, so SEARCH stops.

Lemma 2 (split). The quadratic split of M+1M + 1 entries returns two disjoint groups whose union is the input, each with at least mm entries. Proof. Each step moves one entry from the rest to a group, so the groups stay disjoint and the union is kept. Each group starts with one seed. Before each step, if a group gg has ∣g∣+∣rest∣=m|g| + |\text{rest}| = m, all of the rest goes to gg, which then has mm entries. Otherwise both groups satisfy ∣g∣+∣rest∣>m|g| + |\text{rest}| > m, and one entry is moved, which lowers ∣g∣+∣rest∣|g| + |\text{rest}| by at most 1 for each group, so both sums stay at least mm. When the rest is empty, each group has ∣g∣≥m|g| \ge m. At the start ∣g∣+∣rest∣=1+(M−1)=M≥2m≥m|g| + |\text{rest}| = 1 + (M - 1) = M \ge 2m \ge m, so the induction starts. The other group has at least mm entries because M+1−m≥mM + 1 - m \ge m. □\square

INSERT. Assume (R) holds before the call, and let hh be the height. CHOOSE-LEAF follows one entry per level to a leaf uu (lines L4 and L5), and line L6 adds the new entry. Only the nodes on the path from uu to the root can now break (R): uu may hold M+1M + 1 entries, and the rectangles on the path may no longer be MBRs.

Claim: at the start of each pass of line L7 with node uu at height jj, (R) holds at every node except that uu may have M+1M + 1 entries and the rectangles of the entries for uu and its ancestors may be wrong; all rectangles inside the subtree of uu are correct, and all leaves are at depth hh. This holds for the leaf. If uu has M+1M + 1 entries, line L8 splits them by Lemma 2 into uu and a new node vv of the same kind, each with mm to MM entries; the children moved to vv keep their subtrees, so all rectangles inside the subtrees of uu and vv stay correct, and the leaves below vv keep their depth. If uu is the root, line L10 makes a root with two correct entries for uu and vv; the new root is internal with 2 entries, and every leaf is now at depth h+1h + 1, so (R) holds everywhere and INSERT stops. Otherwise line L9 adds a correct entry for vv to the parent pp, so pp may hold M+1M + 1 entries. In both cases line L11 sets the rectangle of the entry for uu in pp to MBR⁡(u)\operatorname{MBR}(u), so all rectangles inside the subtree of pp are correct, and the claim holds for pp at height j+1j + 1. When line L7 passes the root, the root has at most MM entries and all rectangles are correct, so (R) holds. Each pass goes up one level, so INSERT stops after at most h+1h + 1 passes.

The same argument holds when INSERT is called by line L15 to put an entry (r,c)(r, c) at height j≥1j \ge 1: CHOOSE-LEAF stops at a node of height jj, the subtree of cc has height j−1j - 1, so its leaves land at depth hh, and the rest of the claim is the same.

DELETE. By Lemma 1, the leaf that holds (r,id)(r, id) is below entries whose rectangles contain rr, so line L12 finds it if it is stored, and it answers false only when the entry is not stored. Line L13 removes the entry. CONDENSE-TREE (line L14) goes up the path from that leaf. At each non-root node uu on the path: if uu has fewer than mm entries, it is removed from its parent, and its subtree is kept in QQ with its height; else the rectangle for uu in its parent is set to MBR⁡(u)\operatorname{MBR}(u), which is correct, since the rectangles below uu are correct by induction from the leaf up. After line L14, each remaining node has a correct rectangle, each remaining non-root node has between mm and MM entries (the nodes on the path that kept at least mm were not underfull, and the other nodes did not change), and all remaining leaves are at depth hh. The root may now have only one entry, and if the root is a leaf it may have fewer.

Line L15 reinserts each entry of each node of QQ at the height of that node. By the claim above, each such INSERT keeps parts 1 to 3, except for the possible root with one entry, which INSERT does not create but does not repair either. Each entry of a removed node goes back once, so the set of stored objects is the old set minus (r,id)(r, id). Line L16 replaces an internal root with one entry by its child, which lowers every leaf depth by one and keeps parts 1 and 3; it stops because the height drops by one each time. After it, an internal root has at least 2 entries, and (R) holds.

Termination of DELETE. Line L12 visits each node at most once. Line L14 makes one step per level. Line L15 runs finitely many INSERTs, each of which stops. Line L16 runs at most hh times. ■\blacksquare

Back to R-tree