CSE 326
Disjoint Sets and Dynamic Equivalence
David Kaplan
Dept of Computer Science & Engineering
Autumn 2001
Today’s Outline
Making a “good” maze
Disjoint Set Union/Find ADT
Up-trees
Maze revisited
Weighted Union
Path Compression
An amazeing complexity analysis
Disjoint Sets
CSE 326 Autumn 2001
2
Maze Construction Problem
Represent maze environment as graph {V,E}
collection of rooms: V
connections between rooms (initially all closed): E
Construct a maze:
collection of rooms: V = V
designated rooms in, iV, and out, oV
collection of connections to knock down: E E
such that a unique path connects any two rooms
Disjoint Sets
CSE 326 Autumn 2001
3
The Middle of the Maze
So far, some walls have been
knocked down while others
remain.
Now, we consider the wall
between A and B.
Should we knock it down?
no, if A and B are otherwise
connected
yes, if A and B are not
otherwise connected
Disjoint Sets
CSE 326 Autumn 2001
A
B
4
Maze Construction Algorithm
While edges remain in E
Remove a random edge e = (u, v) from E
If u and v have not yet been connected
- add e to E
- mark u and v as connected
Disjoint Sets
CSE 326 Autumn 2001
5
Equivalence Relations
An equivalence relation R has three properties:
reflexive: for any x, xRx is true
symmetric: for any x and y, xRy implies yRx
transitive: for any x, y, and z, xRy and yRz implies xRz
Connection between rooms is an equivalence relation (call it C)
For any rooms a, b, c
a C a (A room connects to itself!)
If a C b, then b C a
If a C b and b C c, then a C c
Other equivalence relations?
Disjoint Sets
CSE 326 Autumn 2001
6
Disjoint Set Union/Find ADT
Union/Find ADT operations
find(4)
union
find
create
destroy
{1,4,8}
8
{6}
{7} {2,3,6}
{5,9,10}
union(2,6)
{2,3}
Disjoint set equivalence property: every element of a
DS U/F structure belongs to exactly one set
Dynamic equivalence property: the set of an element
can change after execution of a union
Disjoint Sets
CSE 326 Autumn 2001
7
Disjoint Set Union/Find
More Formally
Given a set U = {a1, a2, … , an}
Maintain a partition of U, a set of subsets of U {S1, S2, … , Sk}
such that:
- each pair of subsets Si and Sj are disjoint: Si S j
k
- together, the subsets cover U: U S i
i 1
- The Si are mutually exclusive and collectively exhaustive
Union(a, b) creates a new subset which is the union of a’s subset
and b’s subset
NOTE: outside agent decides when/what to union - ADT is just the bookkeeper
Find(a) returns a unique name for a’s subset
NOTE: set names are arbitrary! We only care that:
Find(a) == Find(b) a and b are in the same subset
Disjoint Sets
CSE 326 Autumn 2001
8
Example
Construct the maze on the right
a
3
2
Initial state (set names underlined):
{a}{b}{c}{d}{e}{f}{g}{h}{i}
Maze constructor (outside agent)
traverses edges in random order and
decides whether to union
d
Disjoint Sets
CSE 326 Autumn 2001
10
1
4
11
g
b
e
6
7
9
12
h
c
f
8
5
9
i
Example, First Step
{a}{b}{c}{d}{e}{f}{g}{h}{i}
a
find(b) b
find(e) e
find(b) find(e) so:
add 1 to E
2
d
3
b
c
10
1
4
11
e
6
f
7
9
8
union(b, e)
g
12
h
i
5
{a}{b,e}{c}{d}{f}{g}{h}{i}
Order of edges in blue
Disjoint Sets
CSE 326 Autumn 2001
10
Up-Tree Intuition
Finding the representative member of a set is
somewhat like the opposite of finding whether a
given item exists in a set.
So, instead of using trees with pointers from
each node to its children; let’s use trees with a
pointer from each node to its parent.
Disjoint Sets
CSE 326 Autumn 2001
11
Union-Find
Up-Tree Data Structure
Each subset is an up-tree
with its root as its
representative member
All members of a given
set are nodes in that
set’s up-tree
Hash table maps input
data to the node
associated with that data
a
d
c
b
h
g
f
i
e
Up-trees are not necessarily binary!
Disjoint Sets
CSE 326 Autumn 2001
12
Find
find(f)
find(e)
a
d
c
b
g
f
a
b 10 c
d
e
11
9
8
g 12 h
i
h
i
7
e
Just traverse to the root!
runtime:
Disjoint Sets
CSE 326 Autumn 2001
13
f
Union
union(a,c)
a
d
c
b
g
f
a
b 10 c
d
e
f
11
9
8
g 12 h
i
h
i
e
runtime:
Disjoint Sets
Just hang one root from the other!
CSE 326 Autumn 2001
14
a
Example (1/11)
3
2
d
4
11
union(b,e)
c
1
6
e
b
c
d
a
b
c
d
e
7
9
g 12 h
a
e
b 10
f
8
5
f
g
h
i
f
g
h
i
i
a
Example (2/11)
b 10
2
d
11
union(a,d)
a
3
6
4
e
c
d
f
g
h
i
f
g
h
i
e
a
b
d
c
e
7
9
g 12 h
b
c
f
8
5
i
a
Example (3/11)
3
d
union(a,b)
4
d
e
c
f
g
h
7
9
g 12 h
b
c
6
11
a
b 10
8
5
i
e
a
b
c
d
e
f
g
h
f
i
i
a
Example (4/11)
b 10
6
d
11
find(d) = find(e)
No union!
4
e
b
c
f
g
h
7
9
g 12 h
a
c
f
8
5
i
i
d
e
While we’re finding e,
could we do anything else?
a
Example (5/11)
b
c
d
e
d
e
11
9
7
g
h
i
a
b
c
d
e
f
g
f
8
g 12 h
f
c
6
union(h,i)
a
b 10
5
h
i
i
a
Example (6/11)
b
c
d
e
f
g
h
i
c
6
union(c,f)
a
b 10
a
b
e
11
9
8
g 12 h
i
c
d
e
d
g
f
7
h
i
f
Example (7/11)
find(e)
find(f)
union(a,c)
a
b
c
d
g
f
h
Could we do a
better job on this union?
b 10
c
d
e
f
11
9
8
g 12 h
i
c
a
i
e
a
b
f
d
e
g
h
i
7
Example (8/11)
find(f)
find(i)
union(c,h)
c
a
b
f
d
e
g
h
a
b 10
c
d
e
f
11
9
8
g 12 h
i
c
a
i
b
f
d
e
g
h
i
Example (9/11)
find(e) = find(h) and find(b) = find(c)
So, no unions for either of these.
c
a
b
f
d
e
a
b 10
c
d
e
f
11
9
g 12 h
g
h
i
i
Example (10/11)
find(d)
find(g)
union(c, g)
f
g
d
e
c
d
e
f
g 12 h
i
g
c
h
a
b
b
11
c
a
a
i
b
f
d
e
h
i
a
b
c
d
e
f
g 12 h
i
g
a
b
c
c
d
e
f
g
h
i
Example (11/11)
find(g) = find(h)
So, no union.
And, we’re done!
a
b
f
d
e
h
i
Ooh… scary!
Such a hard maze!
Disjoint set data structure
A forest of up-trees
can easily be stored
in an array.
a
Also, if the node
b
names are integers or
characters, we can
use a very simple,
perfect hash.
c
g
d
f
h
i
e
Nifty storage trick!
0 (a) 1 (b) 2 (c) 3 (d) 4 (e) 5 (f) 6 (g) 7 (h) 8 (i)
up-index: -1
Disjoint Sets
0
CSE 326 Autumn 2001
-1
0
1
2
-1
-1
26
7
Implementation
typedef ID int;
ID find(Object x) {
assert(hTable.contains(x));
ID xID = hTable[x];
while(up[xID] != -1) {
xID = up[xID];
}
ID union(ID x, ID y) {
assert(up[x] == -1);
assert(up[y] == -1);
up[y] = x;
}
return xID;
}
runtime: O(depth) or …
Disjoint Sets
CSE 326 Autumn 2001
runtime: O(1)
27
Room for Improvement:
Weighted Union
Always makes the root of the larger tree the new root
Often cuts down on height of the new up-tree
a
b
c
d
g h
f
a
i
e
Could we do a
better job on this union?
Disjoint Sets
c
b
g h
f
d
e
CSE 326 Autumn 2001
i
a
b
d
g h
i
c
f
e
Weighted union!
28
Weighted Union Code
typedef ID int;
ID union(ID x, ID y) {
assert(up[x] == -1);
assert(up[y] == -1);
if (weight[x] > weight[y]) {
up[y] = x;
weight[x] += weight[y];
} else {
up[x] = y;
weight[y] += weight[x];
}
new runtime of find:
}
Disjoint Sets
new runtime of union:
CSE 326 Autumn 2001
29
Weighted Union Find Analysis
Finds with weighted union are O(max up-tree height)
But, an up-tree of height h with weighted union must
have at least 2h nodes
Base case: h = 0, tree has 20 = 1 node
Induction hypothesis: assume true for h < h
A merge can only increase tree height by
one over the smaller tree. So, a tree of
max
height
2
n and
height h-1 was merged with a larger tree to
form the new tree. Each tree then has 2h-1
max height log n
hypotheses for a
So, find takes O(log n) nodes by the induction
total of at least 2h nodes. QED.
Disjoint Sets
CSE 326 Autumn 2001
30
Room for Improvement:
Path Compression
Points everything along the path of a find to the root
Reduces the height of the entire access path to 1
a
b
c
f
g
h
i
d
b
e
c
f
g
h
d
e
While we’re finding e,
could we do anything else?
Disjoint Sets
a
CSE 326 Autumn 2001
Path compression!
31
i
Path Compression Example
find(e)
c
a
f
b
i
Disjoint Sets
c
g
h
a
f
b
d
g
h
e
d
i
e
CSE 326 Autumn 2001
32
Path Compression Code
typedef ID int;
ID find(Object x) {
assert(hTable.contains(x));
ID xID = hTable[x];
ID hold = xID;
while(up[xID] != -1) {
xID = up[xID];
}
while(up[hold] != -1) {
temp = up[hold];
up[hold] = xID;
hold = temp;
}
return xID;
}
Disjoint Sets
CSE 326 Autumn 2001
runtime:
33
Complexity of
Weighted Union + Path Compression
Ackermann created a function A(x, y) which grows very fast!
Inverse Ackermann function (x, y) grows very slooooowwwly …
Single-variable inverse Ackermann function is called log* n
How fast does log n grow? log n = 4 for n = 16
Let log(k) n = log (log (log … (log n)))
Then, let log* n = minimum k such that log(k) n 1
How fast does log* n grow? log* n = 4 for n = 65536
log* n = 5 for n = 265536 (20,000 digit number!)
How fast does (x, y) grow? Even sloooowwwer than log* n
(x, y) = 4 for n far larger than the number of atoms in the
universe (2300)
Disjoint Sets
CSE 326 Autumn 2001
34
Complexity of
Weighted Union + Path Compression
Tarjan proved that m weighted union and find
operations on a set of n elements have worst case
complexity O(m(m, n))
This is essentially amortized constant time
In some practical cases, weighted union or path
compression or both are unnecessary because trees
do not naturally get very deep.
Disjoint Sets
CSE 326 Autumn 2001
35
Summary
Disjoint Set Union/Find ADT
Simple ADT, simple data structure, simple code
Complex complexity analysis, but extremely useful
result: essentially, constant time!
Lots of potential applications
Disjoint Sets
Object-property collections
Index partitions: e.g. parts inspection
To say nothing of maze construction
In some applications, it may make sense to have meaningful
(non-arbitrary) set names
CSE 326 Autumn 2001
36
© Copyright 2026 Paperzz