Algorithm Search⌘K

Proofs: Gabow-Tarjan linear-time static union-find

These are the human proofs of Gabow-Tarjan linear-time static union-find, at full length.

The Gabow-Tarjan structure returns the nearest unlinked ancestor full

This proof shows: correctness, termination.

Write ans(v)\mathrm{ans}(v) for the nearest ancestor of vv in TT, vv included, that is not linked. The root of TT is never linked, so ans(v)\mathrm{ans}(v) exists. Links are never undone, so the set of linked nodes only grows.

Lemma 1 (cutting). After INIT: (a) each node is in exactly one microset; (b) each microset SS has at most bb nodes; (c) for each x∈Sx \in S, x.p∈Sx.p \in S or x.p=r(S)x.p = r(S), and if r(S)=NONEr(S) = \mathrm{NONE} then SS contains the root of TT; (d) if x.p∈Sx.p \in S then x.px.p has a smaller number than xx; (e) the number of microsets is at most 2n/b+12n/b + 1.

Proof. Call the list held by a node vv after its step its open list. By induction from the leaves up: the open list of vv starts with vv, is a connected set of nodes whose top is vv, lists each node after its parent, and has fewer than h+1h + 1 nodes, where h=⌈b/2⌉h = \lceil b/2 \rceil. Indeed, vv concatenates the open lists of some of its children into GG, each of size at most hh, closing GG when ∣G∣≥h|G| \ge h, so the part left has fewer than hh nodes, and vv is put in front. Each closed group is a concatenation of open lists of children of vv, each a connected set with top a child of vv and in parent-first order, which gives (c) with r(S)=vr(S) = v and (d). Its size is at least hh, and at most (h−1)+h≤b(h - 1) + h \le b, because GG had fewer than hh nodes before the last list was added; this gives (b). The root closes its own open list with root NONE, a connected set with top the root of TT, of size at most h≤bh \le b. Each node is put in exactly one open list, and moves with it until that list is closed, which gives (a). All closed groups but the last have at least h≥b/2h \ge b/2 nodes, which gives (e). □\square

A piece of SS is a maximal part of SS connected by parent edges inside SS. By (c), the top tt of a piece has t.p=r(S)t.p = r(S), or tt is the root of TT. INIT computes anc(x)\mathrm{anc}(x) in the order of the numbers, so by (d) the value for x.px.p is ready, and anc(x)\mathrm{anc}(x) is the set of nodes on the path from xx up to the top of its piece.

Lemma 2 (micro find). M(S)M(S) is always the set of linked nodes of SS, by line L5. MICRO-FIND(x)(x) returns the deepest unlinked node on the path from xx to the top of its piece, or NONE if all of them are linked. If it returns a node, that node is ans(x)\mathrm{ans}(x).

Proof. u=anc(x)∖M(S)u = \mathrm{anc}(x) \setminus M(S) is the set of unlinked nodes on that path. The nodes of the path have numbers that grow with depth, by (d), so the largest number in uu is the deepest of them, the first one met when walking up from xx. All nodes below it on the path are linked, so it is ans(x)\mathrm{ans}(x). □\square

Call xx exhausted when MICRO-FIND(x)(x) is NONE. This is permanent, since marks only grow.

Lemma 3 (leaving a microset). If xx is exhausted, then r(S(x))≠NONEr(S(x)) \ne \mathrm{NONE} and ans(x)=ans(r(S(x)))\mathrm{ans}(x) = \mathrm{ans}(r(S(x))).

Proof. All nodes from xx to the top tt of its piece are linked. The root of TT is never linked, so tt is not the root, and t.p=r(S(x))t.p = r(S(x)) by (c). The walk from xx to ans(x)\mathrm{ans}(x) passes through tt and continues at t.pt.p, so ans(x)=ans(t.p)\mathrm{ans}(x) = \mathrm{ans}(t.p). □\square

Invariant (N) of the macro forest. For each macro set XX with name zz: z∈Xz \in X, and every y∈Xy \in X with y≠zy \ne z is exhausted and has r(S(y))∈Xr(S(y)) \in X.

Consequence. Let y∈Xy \in X. Follow y,r(S(y)),r(S(r(S(y)))),…y, r(S(y)), r(S(r(S(y)))), \ldots while the current node is not zz. By (N) each step stays in XX, and each step goes to a proper ancestor, so the walk is finite and must stop, which happens only at zz. By Lemma 3, which holds at every moment, each step keeps the answer. So, at every moment, zz is an ancestor of every member of XX (or equal to it), and ans(y)=ans(z)\mathrm{ans}(y) = \mathrm{ans}(z) for every y∈Xy \in X.

At INIT every set is {y}\{y\} with name yy, so (N) holds. A link changes no macro set, and exhaustion is permanent, so (N) stays true. Path compression and union by size change neither the sets nor the names.

Line L12. Here zz is the name of its set XX, and zz is exhausted. Let y=r(S(z))y = r(S(z)), which is not NONE by Lemma 3, so y∈Ry \in R; it is a proper ancestor of zz. Let YY be its set, with name z′z', which is an ancestor of yy by the consequence. If Y=XY = X, then zz would be an ancestor of yy, a proper ancestor of zz, which is impossible. So X≠YX \ne Y and the union merges two sets, with the name z′z'. For the merged set: the members of YY other than z′z' satisfy (N) as before; the members of XX other than zz are exhausted and have their r(S(⋅))r(S(\cdot)) in XX, which is in the merged set; and zz is exhausted with r(S(z))=yr(S(z)) = y in the merged set. So (N) holds.

FIND is correct. If line L9 returns, the answer is right by Lemma 2. Otherwise vv is exhausted and ans(v)=ans(r(S(v)))\mathrm{ans}(v) = \mathrm{ans}(r(S(v))) by Lemma 3. Line L10 sets zz to the name of the set of r(S(v))r(S(v)), so ans(z)=ans(v)\mathrm{ans}(z) = \mathrm{ans}(v) by the consequence of (N). The loop keeps ans(z)=ans(v)\mathrm{ans}(z) = \mathrm{ans}(v), because line L12 keeps (N) and line L13 takes the new name. When the loop stops, $w = $ MICRO-FIND(z)≠NONE(z) \ne \mathrm{NONE}, and w=ans(z)=ans(v)w = \mathrm{ans}(z) = \mathrm{ans}(v) by Lemma 2.

Termination. Each pass through lines L12 and L13 merges two different macro sets, so the loop runs at most ∣R∣−1|R| - 1 times over the whole run. MICRO-FIND and LINK take O(1)O(1) steps, and the macro finds terminate because the macro forest is a forest. INIT walks each node a constant number of times. ■\blacksquare

Back to Gabow-Tarjan linear-time static union-find