Union Find
- Let
be a graph. A partition of is a collection of sets such that: for all for all
- makeSet(v) - given a (pointer to) vertex v, add the singleton set {v} to P
- union(
) - given (pointers to) the cells and , remove these from and add the cell - find(v) - given a (pointer to) vertex v, return (a pointer to) the cell of P containing v
union-find(V, E)
let P = empty set
for v in V:
makeSet(v)
for (u, v) in E:
if find(u) != find(v)
union(find(u), find(v))
- A naive implementation of union-find runs in
.
Optimisation
- we ensure that always the smaller cell is added into the bigger cell by adding a size heuristic. In makeSet(
) set size to 1 and update size in union.
Lemma: In a series of operations of makeSet, union and find on
Proof: Whenever the cell value of a node changes, its cardinality will at-least double (only way cells get merged is if its size is bigger than some other cell). But
-
With this implementation, the running-time of union find is
. Total number of calls to makeSet, union and find is , and each union will update cell pointer times. -
Further optimisation can be done by representing cells as trees. The union operation now simply updates the parent pointer and updates size. More in the find operation we flatten the tree as we go along i.e.
find(v)
if v -> parent is not a root:
v -> parent = find(v -> parent)
return v -> parent