Algorithm Search⌘K

Proofs: Quick-union

These are the human proofs of Quick-union, at full length.

Quick-union keeps a forest whose trees are the sets full

This proof shows: correctness, termination.

Let the elements be 00 to n−1n - 1, and let ≡\equiv be the equivalence closure of the pairs of the unions done so far, as in the dynamic equivalence problem. Call rr a root when parent[r]=r\mathrm{parent}[r] = r. We prove that after each operation:

(U1) For each xx, the sequence x,parent[x],parent[parent[x]],…x, \mathrm{parent}[x], \mathrm{parent}[\mathrm{parent}[x]], \ldots reaches a root within n−1n - 1 steps. Write root(x)\mathrm{root}(x) for that root.

(U2) For all x,yx, y: root(x)=root(y)\mathrm{root}(x) = \mathrm{root}(y) if and only if x≡yx \equiv y.

(U3) The counter equals the number of roots.

Initialization. After lines L1 and L2, every element is a root, so (U1) holds with 0 steps and root(x)=x\mathrm{root}(x) = x. No union has been done, so ≡\equiv is equality, and (U2) holds. There are nn roots and the counter is nn.

Find. Assume (U1). FIND(p)(p) follows the same sequence as in (U1): the loop of lines L3 and L4 replaces pp by its parent while pp is not a root. By (U1) it reaches a root after at most n−1n - 1 steps, so it stops, and line L5 returns root(p)\mathrm{root}(p). It writes nothing, so (U1) to (U3) still hold. By (U2), connected(p, q) returns true exactly when p≡qp \equiv q.

Union. Assume (U1) to (U3) before UNION(p,q)(p, q). Line L6 sets i=root(p)i = \mathrm{root}(p) and j=root(q)j = \mathrm{root}(q), by the find case.

Case i=ji = j. By (U2), p≡qp \equiv q, so the new relation ≡′\equiv' equals ≡\equiv. Line L7 returns, nothing changes, and the invariants hold.

Case i≠ji \ne j. Line L8 sets parent[i]=j\mathrm{parent}[i] = j, the only change to the array. Let Ti={x:root(x)=i}T_i = \{x : \mathrm{root}(x) = i\} and Tj={x:root(x)=j}T_j = \{x : \mathrm{root}(x) = j\} before the union.

(U1). Take any xx. If x∉Tix \notin T_i, the path from xx to its root does not pass through ii, since a path that reaches ii ends at ii, a root. So none of its parents changed, and the path is the same as before. If x∈Tix \in T_i, the old path from xx ends at ii with no repeated node; its nodes are distinct, because a repeated node would make a cycle that never reaches a root. Now it continues from ii to jj and then along the old path from jj to jj, which is empty because jj is a root. So the new path from xx is the old path followed by one edge to jj, and jj is still a root. The nodes of this path are distinct: the old path lies in TiT_i, and j∈Tjj \in T_j, which does not meet TiT_i. A path of distinct nodes has at most n−1n - 1 edges. So (U1) holds, with root′(x)=j\mathrm{root}'(x) = j for x∈Ti∪Tjx \in T_i \cup T_j and root′(x)=root(x)\mathrm{root}'(x) = \mathrm{root}(x) otherwise.

(U2). By (U2) before the union, TiT_i is the class of pp and TjT_j the class of qq under ≡\equiv. The relation ≡′\equiv' adds the pair (p,q)(p, q), and its classes are those of ≡\equiv with TiT_i and TjT_j replaced by Ti∪TjT_i \cup T_j: this set is one class because p≡′qp \equiv' q, and no chain of pairs leaves it, since each pair of ≡\equiv stays inside one old class and the new pair joins TiT_i and TjT_j. The new roots are jj on Ti∪TjT_i \cup T_j and the old roots elsewhere, so equal roots mean one class of ≡′\equiv'.

(U3). The element ii is no longer a root and no other element changes, so the number of roots falls by one, and line L9 lowers the counter by one.

Conclusion. By induction on the number of operations, (U1) to (U3) hold after each operation. Each find stops and returns a representative that is the same for exactly the elements of one class, which is what the disjoint-set type requires. ■\blacksquare

Back to Quick-union