Algorithm Search⌘K

Proofs: Quick-find

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

Quick-find keeps one name per set and answers each query correctly full

This proof shows: correctness, termination.

Let the elements be 00 to n−1n - 1. For a sequence of operations, let ≡\equiv be the equivalence closure of the pairs of the unions done so far, as in the dynamic equivalence problem. We prove that after each operation:

(Q) For all x,yx, y: id[x]=id[y]\mathrm{id}[x] = \mathrm{id}[y] if and only if x≡yx \equiv y. Each value id[x]\mathrm{id}[x] is an element rr with r≡xr \equiv x and id[r]=r\mathrm{id}[r] = r. The counter equals the number of classes of ≡\equiv.

Termination. Each operation runs at most one loop of nn steps, so it stops.

Initialization. After lines L1 and L2, id[x]=x\mathrm{id}[x] = x for each xx, and no union has been done, so ≡\equiv is equality. Then id[x]=id[y]\mathrm{id}[x] = \mathrm{id}[y] if and only if x=yx = y, each xx is its own name, and there are nn classes. So (Q) holds.

Find and connected. These change nothing, so (Q) still holds. By (Q), connected(p, q) returns true exactly when p≡qp \equiv q, and find(p) returns an element equivalent to pp that is the same for all members of the class of pp.

Union. Assume (Q) before UNION(p,q)(p, q). Let ≡\equiv be the relation before and ≡′\equiv' the relation after, the closure of ≡\equiv and the pair (p,q)(p, q). Let a=id[p]a = \mathrm{id}[p] and b=id[q]b = \mathrm{id}[q] be the values that line L4 saves, and let A={x:id[x]=a}A = \{x : \mathrm{id}[x] = a\} and B={x:id[x]=b}B = \{x : \mathrm{id}[x] = b\}. By (Q), AA is the class of pp and BB is the class of qq.

Case a=ba = b. Then p≡qp \equiv q by (Q), so ≡′=≡\equiv' = \equiv. Line L5 returns with no change, and (Q) holds.

Case a≠ba \ne b. Then AA and BB are two different classes, and ≡′\equiv' has the classes of ≡\equiv except that AA and BB are replaced by A∪BA \cup B. Indeed, A∪BA \cup B is closed under ≡′\equiv': an element ≡′\equiv'-related to a member of A∪BA \cup B is linked to it by a chain of pairs of ≡\equiv and the pair (p,q)(p, q), and each such step stays inside A∪BA \cup B or inside a class of ≡\equiv that meets A∪BA \cup B, which is AA or BB. And all of A∪BA \cup B is one class of ≡′\equiv', since p≡′qp \equiv' q. The other classes do not meet A∪BA \cup B, and they stay classes of ≡′\equiv'.

The loop of lines L6 and L7 compares each id[i]\mathrm{id}[i] with the saved value aa, which the loop does not change. Loop invariant: before the step with index ii, each j<ij < i with an old value aa now has the value bb, and every other entry has its old value. It holds for i=0i = 0. The step with index ii writes bb to entry ii exactly when its value is aa, and the value at ii is still the old one, because only earlier entries have changed. So the invariant holds for i+1i + 1. At the end, i=ni = n: the entries of AA have the value bb, and all other entries are unchanged.

After the loop, the elements with value bb are A∪BA \cup B, and for each other old value c∉{a,b}c \notin \{a, b\} the elements with value cc are the same class as before. So equal values mean one class of ≡′\equiv', which is the first part of (Q). The name bb is in B⊆A∪BB \subseteq A \cup B, and id[b]=b\mathrm{id}[b] = b was true before and is not changed, since b∉Ab \notin A. The names of the other classes do not change. Two classes merge into one, so the number of classes falls by one, and line L8 lowers the counter by one. So (Q) holds after the union.

Conclusion. By induction on the number of operations, (Q) holds after each operation, so each connected and find answers as the disjoint-set type requires, and the counter is the number of sets. ■\blacksquare

Back to Quick-find