Disjoint Set Operations
Kruskal’s Algorithm
8 7
B C D
4 9
2
11 4
A I 14 E
7 6
8 10
1 2
H G F
2
Union-Find
• Make-Set(x)
• Creates a new set whose
only member is x
• O(1) 8 7
B C D
4 9
• MakeUnionFind(S) 2
11 4
• MakeSet(x) with each v \in A I 14 E
V
8 7 6
10
H
1 G 2 F
3
Union-Find
• Find(x)
• Return a pointer to the
representative/name of the
set containing x 8 7
B C D
• Find(C) = Red/ Pointer to C
4 9
or I 2
11 4
A I 14 E
8 7 6
10
H
1 G 2 F
4
Union-Find
• Find(x)
• Return a pointer to the
representative/name of the
set containing x 8 7
B C D
• Find(C) = Red/ Pointer to C
4 9
or I 2
11 4
A I 14 E
• Union(x, y)
• Unites two disjoint, 8 7 6
10
dynamic sets that contain x 1 2
H G F
and y, say and
5
Union-Find
• Maintain an array
Component
• Contains the name of the
set currently containing 8 7
B C D
each element.
4 9
2
11 4
• Name of the set A I 14 E
• Pointer to a representative
node 8 7 6
10
• Name of the representative 1 2
H G F
node
6
Union-Find
Components
1 1 3 4 5 6 6 6 3
• Maintain an array Component
1 2 3 4 5 6 7 8 9
• Contains the name of the set
currently containing each
element. 8 7
2 3 4
• Name of the set 4 9
2
• Pointer to a representative 11 4
node 1 9 14 5
• Name of the representative
node 8 7 6
10
• Index of the representative 8
1 7 2 6
node
7
Union-Find
Components
1 2 3 4 5 6 7 8 9
• Initially set for all s. 1 2 3 4 5 6 7 8 9
8 7
2 3 4
4 9
2
11 4
1 9 14 5
8 7 6
10
8
1 7 2 6
8
Union-Find
Components
1 1 3 4 5 6 7 8 9
• Initially set for all s. 1 2 3 4 5 6 7 8 9
• Union(x, y) merges two 2
8 3
7
4
disjoint sets together
4 9
• Update the values of for all 2
elements in sets A and/or B 11 4
1 9 14 5
8 7 6
10
8
1 7 2 6
9
Union-Find
Components
1 1 3 4 5 6 6 6 3
• Initially set 1 2 3 4 5 6 7 8 9
Component[s]=s for all s
8 7
2 3 4
• Union(x, y) merges two
4 9
disjoint sets together 2
• Update the values of 11 4
Component[s] for all 1 9 14 5
elements in sets A and/or B
8 7 6
10
8
1 7 2 6
10
Union-Find
Components
1 1 3 4 5 3 3 3 3
• Initially set 1 2 3 4 5 6 7 8 9
Component[s]=s for all s
8 7
2 3 4
• Union(x, y) merges two
4 9
disjoint sets together 2
• Update the values of 11 4
Component[s] for all 1 9 14 5
elements in sets A and B
8 7 6
• Scan all the components 10
• Can take 8
1 7 2 6
11
Union-Find
Components
1 1 3 4 5 3 3 3 3
• Find(x) 1 2 3 4 5 6 7 8 9
• Return Components[x]
• Takes
8 7
2 3 4
4 9
2
11 4
1 9 14 5
8 7 6
10
8
1 7 2 6
12
Union-Find
Components
1 1 3 4 5 3 3 3 3
• Optimizations to improve
1 2 3 4 5 6 7 8 9
the Union(x, y)
• Maintain the list of
8 7
elements in each 2 3 4
component 4 9
• Only update the 2
11 4
elements in the smaller 1 9 14 5
set; Keep the name of
the larger set 8 7 6
10
8
1 7 2 6
• Still
13
Union-Find
• Any sequence of k Union operations takes at most time
• Touches at most 2k elements of S
• A node v’s set grows after each Union operation
• Either Component[v] remains unchanged, or it is updated
• If updated the size of v’s set doubles
• There can be at most updates to Component[v]
• For 2k node, there can be at most updates.
A Better Union-Find Parents
1 2 3 4 5 6 7 8 9
• Each node v will point to 1 2 3 4 5 6 7 8 9
the representative node of
its set.
8 7
2 3 4
4 9
• MakeUnionFind(S) 2
initializes a record for 11 4
1 9 14 5
each element v with a
pointer that points to itself 7 6
8 10
• To indicate that v is in its 1 2
own set. 8 7 6
A Better Union-Find
• Consider a Union(x, y)
• Set either x or y be the name of the combined set (preferably
from the larger set)
• Assume we select y as the name.
• Simply update x’s pointer to point to y.
• We do not update the pointers at the other nodes in x’s set.
A Better Union-Find Parents
1 2 3 4 5 6 8 8 9
• Consider a Union(x, y) 1 2 3 4 5 6 7 8 9
• Set either x or y be the
name of the combined set
• Assume we select y as the 8 7
2 3 4
name.
4 9
• Simply update x’s pointer 2
to point to y. 11 4
1 9 14 5
• We do not update the
pointers at the other nodes 7 6
in x’s set. 8 10
8
1 7 2 6
A Better Union-Find Parents
1 2 3 4 5 6 8 8 3
• Consider a Union(x, y) 1 2 3 4 5 6 7 8 9
• The idea is to have either x
or y be the name of the
combined set 8 7
2 3 4
• Assume we select y as the
4 9
name. 2
• Simply update x’s pointer 11 4
to point to y. 1 9 14 5
• We do not update the 6
8 7
pointers at the other nodes 10
in x’s set. 8
1 7 2 6
A Better Union-Find Parents
1 2 3 4 5 7 8 8 3
• Consider a Union(x, y) 1 2 3 4 5 6 7 8 9
• The idea is to have either x
or y be the name of the
combined set 8 7
2 3 4
• Assume we select y as the
4 9
name. 2
• Simply update x’s pointer 11 4
to point to y. 1 9 14 5
• We do not update the 6
8 7
pointers at the other nodes 10
in x’s set. 8
1 7 2 6
A Better Union-Find Parents
1 1 3 4 5 7 8 8 3
• Consider a Union(x, y) 1 2 3 4 5 6 7 8 9
• The idea is to have either x
or y be the name of the
combined set 8 7
2 3 4
• Assume we select y as the
4 9
name. 2
• Simply update x’s pointer 11 4
to point to y. 1 9 14 5
• We do not update the 6
8 7
pointers at the other nodes 10
in x’s set. 8
1 7 2 6
A Better Union-Find Parents
1 1 6 4 5 7 8 8 3
• Consider a Union(x, y) 1 2 3 4 5 6 7 8 9
• The idea is to have either x
or y be the name of the
combined set 8 7
2 3 4
• Assume we select y as the
4 9
name. 2
• Simply update x’s pointer 11 4
to point to y. 1 9 14 5
• We do not update the 6
8 7
pointers at the other nodes 10
in x’s set. 8
1 7 2 6
A Better Union-Find
Parents
1 1 6 4 5 7 8 8 3
• Union(x, y) 1 2 3 4 5 6 7 8 9
• Takes O(1)
8 7
2 3 4
• Find(x)
• Cannot simply return 4 9
2
Parents[s] 4
11
• Traverse through the 1 9 14 5
pointers to the top
• No longer O(1) 8 7 6
10
8
1 7 2 6
A Better Union-Find
• Find operation takes O(log n) time
• Every time the name of the set containing node v changes,
the size of this set at least doubles.
• There can be at most n nodes in a set
• There can be at most name changes
• Find operation has complexity
A Better Union-Find
def MakeUnionFind(n) def find(x):
for i = 1 to n if parent[x] == x
parent[i] = i return parent[x]
else
def Union(x, y): return find(parent[x])
# Assuming x and y are
# from two disjoint sets.
if x’s set is larger
parent[y] = x
else
parent[x] = y
A Better Union-Find with Path
Compression
def MakeUnionFind(n) def find(x):
for i = 1 to n if parent[x] == x
parent[i] = i return x
else
def Union(x, y): parent[x] = find(parent[x])
# Assuming x and y are return parent[x]
# from two disjoint sets.
if x’s set is larger
parent[y] = x
else
parent[x] = y
Reference
• Union-Find
• KT Section 4.6