SlideShare a Scribd company logo
CICS 210
Data Structures
Union-Find
V1 - 11/24/2024
MJ Golin
CICS Fall 2024
2
Outline
• Union Find
• Introduction
• First version
• Up-trees
• Union by size
• Going further
3
The Union Find Problem
• We’re now returning to graph connectivity.
• Will see an algorithm for being able to answer graph connectivity updates quickly.
• This will actually be an algorithm for set maintenance (under insertions).
1
9 3
5
4 8
7
6
11
10
2
12
13
Recall graph connectivity (undirected graphs).
• Two vertices in a graph are connected
if there exists a path from one to the other.
• A connected component is a maximal
subgraph in which every vertex is connected
to every other vertex.
Graph to the left has 3 connected components.
4
The Union Find Problem
• We’re now returning to graph connectivity
• Will see an algorithm for being able to answer graph connectivity updates quickly
• This will actually be an algorithm for set maintenance (under insertions)
1
9 3
5
4 8
7
6
11
10
2
12
13
Connected(a,b): query that returns true if and only
if a and b are in the same connected component.
A B C
Find(a): query that returns the name of the
component containing a.
Find(3) = Find(6) = A; Find(2) = C
5
The Union Find Problem
Note that Connected(a,b) is only asking whether a,b are in the same connected component set.
A Union (a,b) will merge the two sets if a,b are in different sets. If they’re in the same set it will do nothing
We stated this “connected” problem in a graph but
remember, graphs model relationships. So this
problem can be applied to anything that can be
modeled by a relationship graph, e.g.,
• Pixels in a digital photo.
• Computers in a network.
• Friends in a social network.
• Transistors in a computer chip.
• Elements in a mathematical set.
• Variable types in a program.
We should also point out that connected components in graphs model “equivalence
relations”. So we’re really trying to figure out if two item are equivalent to each other in an
equivalence relation.
1
9 3
5
4 8
7
6
11
10
2
12
13
6
The Union Find Problem
Suppose that we start with no edges.
The problem is to add edges and keep track of them in such a way that we can always
answer Connected(a,b) efficiently. Union (a,b) will denote adding the edge (a,b).
1
9 3
5
4 8
7
6
Connected(4,7)?
Union(4,9)
𝐹𝑎𝑙𝑠𝑒
𝑇𝑟𝑢𝑒
Union(3,5)
Connected(4,8)? 𝐹𝑎𝑙𝑠𝑒
Union(3,8)
Connected(5,8)?
Connected(1,4)? 𝐹𝑎𝑙𝑠𝑒
Union(1,9)
Union(9,5)
Connected(4,8)? 𝑇𝑟𝑢𝑒
Union(1,3)
7
The Union Find Problem
Note that Connected(a,b) is only asking whether a,b are in the same connected component set.
A Union (a,b) will merge the two sets if a,b are in different sets. If they’re in the same set it will do nothing
1
9 3
5
4 8
7
6
Connected(4,7)?
Union(4,9)
𝐹𝑎𝑙𝑠𝑒
𝑇𝑟𝑢𝑒
Union(3,5)
Connected(4,8)? 𝐹𝑎𝑙𝑠𝑒
Union(3,8)
Connected(5,8)?
Connected(1,4)? 𝐹𝑎𝑙𝑠𝑒
Union(1,9)
Union(9,5)
Connected(4,8)? 𝑇𝑟𝑢𝑒
Union(1,3)
1 3 {4} 5 6 7 8 {9}
1 3 {4,9} 5 6 7 8
1 3,5 {4,9} 6 7 8
1 3,5,8 {4,9} 6 7
3,5,8 {1,4,9} 6 7
1,3,5,8,4,9 6 7
No Change!
8
The Union Find Problem
Note that Connected(a,b) is only asking whether a,b are in the same connected component set.
A Union (a,b) will merge the two sets if a,b are in different sets. If they’re in the same set it will do nothing
1
9 3
5
4 8
7
6
We know how to find connected components in time linear in
𝑂(𝑉 + 𝐸) but we don’t want to have to redo the entire
algorithm every time we change the graph by adding an edge.
We’re now going to develop an algorithm for doing this more
efficiently. Our algorithm will be for set maintenance.
9
The Union Find Problem
Assume that out items (vertices) are integers on [0, 𝑛 − 1]
Want to support
• union(p, q) - add an edge between p and q, placing them into the same connected component
• find(p) - return the component id (an int) for the vertex p
• connected(p, q) - true if and only if p and q are in the same component
Every item will have an (integer) id that is the name of the component it belongs.
Since connected(p, q) == (find(p) == find(q))
it is unnecessary to derive it further
public interface UnionFind {
int find(int p);
void union(int p, int q);
boolean connected(int p, int q);
}
10
Outline
• Union Find
• Introduction
• First version
• Up-trees
• Union by size
• Going further
11
First Simple Version
1
2 3
5
4 0
𝑖 0 1 2 3 4 5
𝑖𝑑[𝑖] 0 1 1 0 2 1
• union(p, q) – change all
entries whose id equals 𝑖𝑑[𝑝]
to 𝑖𝑑[𝑞]
• find(p) – return 𝑖𝑑[𝑝]
union(2, 0)
1
2 3
5
4 0
𝑖 0 1 2 3 4 5
𝑖𝑑[𝑖] 0 0 0 0 2 0
12
public class QuickFindUF implements UnionFind {
private int[] id;
public QuickFindUF(int N) {
id = new int[N];
for (int i = 0; i < N; i++) {
id[i] = i; // each in own component to start
}
}
public int find(int p) {
return id[p];
}
public void union(int p, int q) {
int pid = id[p];
int qid = id[q];
for (int i = 0; i < id.length; i++) {
if (id[i] == pid) {
id[i] = qid;
}
}
}
public boolean connected(int p, int q) {
return find(p) == find(q);
}
}
Initialize by having every item in its
own component (setting id[i]=i)
find(p) just returns p’s ID
union(p,q) sets the id of
everyone in same set as p to id[q]
connected(p,q) returns whether
p and q are in the same set
13
First Simple Version
1
2 3
5
4 0
𝑖 0 1 2 3 4 5
𝑖𝑑[𝑖] 0 1 1 0 2 1
• union(p, q) – change all entries
whose id equals 𝑖𝑑[𝑝] to 𝑖𝑑[𝑞]
• find(p) – return 𝑖𝑑[𝑝]
union(2, 0)
1
2 3
5
4 0
𝑖 0 1 2 3 4 5
𝑖𝑑[𝑖] 0 0 0 0 2 0
Bad running time.
Can take 𝑂 𝑉 time per step
Sequence
union(0,1)
union(1,2)
union(2,3)
…
union(n-2,n-1)
would take Θ 𝑛2
time.
14
Outline
• Union Find
• Introduction
• First version
• Up-trees
• Union by size
• Going further
15
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 3 2 9 3 9 5 6 2 9 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝.
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
The highest item in an up-tree is its root.
The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
0
1
2 3
4
5
6 7
8
9
• Items are decomposed into trees.
• 𝑖𝑑[𝑖] is parent of 𝑖 in its tree
• root 𝑖 is identified by 𝑖𝑑 𝑖 = 𝑖
16
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 3 2 9 3 9 5 6 2 9 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝.
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
The highest item in an up-tree is its root.
The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the
up-tree containing 𝑝.
Example:
𝑓𝑖𝑛𝑑 7 = 𝑓𝑖𝑛𝑑 2 = 𝑓𝑖𝑛𝑑 9 = 9
𝑓𝑖𝑛𝑑 0 = 𝑓𝑖𝑛𝑑 3 = 3
𝑓𝑖𝑛𝑑 5 = 5
0
1
2 3
4
5
6 7
8
9
17
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 3 2 9 3 9 5 6 2 9 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝.
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
The highest item in an up-tree is its root.
The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
union(p, q) – if 𝑝 and 𝑞 are in different sets, merge
the sets by setting the id of the root of the up-tree
containing 𝑝 to be the root of the up-tree containing 𝑞
i.e., 𝑖𝑑 𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞).
0
1
2 3
4
5
6 7
8
9
Example: 𝑢𝑛𝑖𝑜𝑛(0,1)
X
X
9
Sets 𝑖𝑑 3 = 𝑓𝑖𝑛𝑑 1 = 9
18
Outline
• Union Find
• Introduction
• First version
• Up-trees
• Union by size
• Going further
19
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 0 1 2 3 4 5 6 7 8 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝.
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝.
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑 𝑝 = 𝑓𝑖𝑛𝑑 𝑞 .
0 1 2 3 4 5 6 7 8 9
20
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 0 1 2 3 4 5 6 7 8 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0 1 2 3 4 5 6 7 8 9
Union(1,2)
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
21
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 0 2 2 3 4 5 6 7 8 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0 1
2
3 4 5 6 7 8 9
Union(1,2) Now Find(1)=Find(2)=2
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
22
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 0 2 2 3 4 5 6 7 8 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0 1
2
3 4 5 6 7 8 9
Union(7,2)
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
23
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 0 2 2 3 4 5 6 2 8 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0 1
2
3 4 5 6
7 8 9
Union(7,2) Now Find(1)=Find(2)=Find(7)=2
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
24
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 0 2 2 3 4 5 6 2 8 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0 1
2
3 4 5 6
7 8 9
Union(8,9)
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
25
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 0 2 2 3 4 5 6 2 9 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0 1
2
3 4 5 6
7 8
9
Union(8,9) Now Find(8)=Find(9)=9
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
26
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 0 2 2 3 4 5 6 2 9 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0 1
2
3 4 5 6
7 8
9
Union(7,8) This will set 𝑖𝑑 𝑓𝑖𝑛𝑑 7 = 𝑖𝑑 𝑓𝑖𝑛𝑑 8
𝑖𝑑 2 = 𝑖𝑑 9 = 9
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
27
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 0 2 9 3 4 5 6 2 9 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0 1
2
3 4 5 6
7
8
9
Union(7,8)
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
28
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 0 2 9 3 4 5 6 2 9 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0 1
2
3 4 5 6
7
8
9
Union(0,3)
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
29
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 3 2 9 3 4 5 6 2 9 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0
1
2 3
4 5 6
7
8
9
Union(0,3)
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
30
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 3 2 9 3 4 5 6 2 9 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0
1
2 3
4 5 6
7
8
9
Union(8,2) Since Find(8)=Find(2)=9 this does nothing
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
31
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 3 2 9 3 4 5 6 2 9 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0
1
2 3
4 5 6
7
8
9
Union(4,7) Sets id[4]=Find(7)=9
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
32
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 3 2 9 3 9 5 6 2 9 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0
1
2 3
4
5 6
7
8
9
Union(4,7) Sets id[4]=Find(7)=9
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
33
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 3 2 9 3 9 5 6 2 9 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0
1
2 3
4
5 6
7
8
9
Union(1,4) Since Find(1)=Find(4)=9 this does nothing
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
34
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 3 2 9 3 9 5 6 2 9 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0
1
2 3
4
5 6
7
8
9
Union(0,5)
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
35
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 3 2 9 5 9 5 6 2 9 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0
1
2 3
4
5
6
7
8
9
Union(0,5)
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
36
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 3 2 9 5 9 5 6 2 9 9
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0
1
2 3
4
5
6
7
8
9
Union(7,6)
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
37
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 3 2 9 5 9 5 6 2 9 6
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0
1
2
3
4
5
6
7
8
9
Union(7,6)
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
38
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 3 2 9 5 9 5 6 2 9 6
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0
1
2
3
4
5
6
7
8
9
Union(2,0)
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
39
2nd version: Up trees
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 3 2 9 5 9 5 5 2 9 6
7
6
8
9
Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝
Sets (items in the same component) will be represented
by up-trees. Every item will start in its component, with
𝑖𝑑 𝑝 = 𝑝.
In the general scenario, the items in a component will
be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of
another item in the same set “above it” in the up-tree.
0
1
2
3
4
5
6
7
8
9
Union(2,0)
• find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of
the up-tree containing 𝑝
• union(p, q) – if 𝑝 and 𝑞 are in different sets,
merge the sets by setting the id of the root of
the up-tree containing 𝑝 to be the root of the
up-tree containing 𝑞
i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞)
The highest item in an up-tree is its root. The root 𝑖 of the
up-tree has 𝑖𝑑 𝑖 = 𝑖;
40
public class QuickUnion implements UnionFind {
private int[] id;
public QuickUnion(int N) {
id = new int[N];
for (int i = 0; i < N; i++) {
id[i] = i; // each in own component to start
}
}
public int find(int p) {
while (p != id[p]) {
p = id[p];
}
return p;
}
public void union(int p, int q) {
id[find(p)] = find(q);
}
public boolean connected(int p, int q) {
return find(p) == find(q);
}
}
Same as before
Returns the root of the tree that contains p.
Does this by walking up parents in tree until it finds
the root, which is the node satisfying 𝑖 = 𝑖𝑑 𝑖 .
union(p,q) points root of tree containing p to root of
tree containing q.
Note: If find[p]=find[q] it points root to itself, not
changing anything.
41
Outline
• Union Find
• Introduction
• First version
• Up-trees
• Union by size
• Going further
42
3rd version: Up trees with Union by size
Suppose we did
union(0,1)
union(0,2)
union(0,3)
…
union(0,n-1)
What would happen?
0
1
0
1
2
0
1
2
3
0
1
2
3
𝑛 − 2
n − 1
How much time would this require?
After the first 𝑖 unions, it takes 𝑖 − 1 steps to implement 𝑓𝑖𝑛𝑑 0 , so total work is σ𝑖=1
𝑛−1
𝑖 − 1 = Θ(𝑛2)
The problem is that the trees built are long and narrow.
Can you see a way to fix this?
43
3rd version: Union by size
The problem was that we made the root of a small tree (one node) the parent of the larger tree.
One fix (that works) is to look at the size of the trees and make the root of the LARGER one the root of the combined tree.
As an example, consider this scenario we saw earlier
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 0 2 2 3 4 5 6 2 9 9
7
6
8
9
0 1
2
3 4 5 6
7 8
9
As an example, consider this scenario we saw earlier
We were asked to do Union(7,8) so we pointed 2 to 9
Since we are doing Union by size, we would point 9 to 2 instead.
44
3rd version: Union by size
The problem was that we made the root of a small tree (one node) the parent of the larger tree.
One fix (that works) is to look at the size of the trees and make the root of the LARGER one the root of the combined tree.
As an example, consider this scenario we saw earlier
1
2 3
5
4
0
𝑖 0 1 2 3 4 5 6 7 8 9
𝑖𝑑[𝑖] 0 2 2 3 4 5 6 2 9 2
7
6
8
9
0 1
2
3 4 5 6
7
8
9
As an example, consider this scenario we saw earlier
We were asked to do Union(7,8) so we pointed 2 to 9
Since we are doing Union by size, we would point 9 to 2 instead.
45
3rd version: Union by size (Implementation)
The problem was that we made the root of a small tree (one node) the parent of the larger tree.
One fix (that works) is to look at the size of the trees and make the root of the LARGER one the root of the combined tree.
For each node: Also keep a size variable sz[i].
sz[i] will be the number of nodes in the tree rooted at i (only used if 𝑖 is the root of its up-tree)
public void union(int p, int q) {
int i = find(p);
int j = find(q);
if (i == j) return;
if (sz[i] < sz[j]) {
id[i] = j;
sz[j] += sz[i];
} else {
id[j] = i;
sz[i] += sz[j];
}
}
i, j are the roots of the two trees
If tree rooted at i is larger, make i the root
Otherwise, make j the root the roots of the two trees
In both cases update the size of the root of the combined tree to reflect
thatit now contains everything
46
3rd version: Up trees with Union by size
Suppose we now redo our quadratic bad case using union by size
union(0,1)
union(0,2)
union(0,3)
…
union(0,n-1)
Then we would get
0
1
0
1
2 3 0 2 3
𝑛 − 2 n − 1
This only takes 𝑂 1 time per step.
We’ll now see that, when using union by size, the trees never get higher than log2 𝑛, so no
find or union step requires more than 𝑂(log 𝑛) time.
0
1
2 …
47
3rd version: Up trees with Union by size
Theorem: For any 𝑥 let 𝑑 𝑥 be the depth of 𝑥 in its up-tree and 𝑠𝑖𝑧𝑒(𝑥) the #
of nodes in its up-tree. Then 2𝑑(𝑥)
≤ 𝑠𝑖𝑧𝑒 𝑥 .
Let 𝑛 be the total # of nodes.
This means that every union and find operation takes 𝑂(log 𝑛) time
Assume theorem is true
Since, for every 𝑥, 2𝑑(𝑥)
≤ 𝑠𝑖𝑧𝑒 𝑥 ≤ 𝑛,
we get 𝑑 𝑥 ≤ log2 𝑛 ,
which means that 𝑓𝑖𝑛𝑑(𝑥) never takes more than log2 𝑛 steps.
In particular, 𝑛 operations takes 𝑂 𝑛 𝑙𝑜𝑔 𝑛 time, a big improvement from
the 𝑂(𝑛2
) of the previous version.
48
3rd version: Up trees with Union by size
• At start, for every node 𝑥, 𝑑(𝑥) = 0 and 𝑠𝑖𝑧𝑒 𝑥 = 1, so 2𝑑(𝑥) = 1 = 𝑠𝑖𝑧𝑒 𝑥 .
• Since 𝑑 𝑥 ≤ 𝑑′(𝑥) and 𝑠𝑖𝑧𝑒 𝑥 ≤ 𝑠𝑖𝑧𝑒′ 𝑥 , this can only be violated if 𝑑′ 𝑥 > 𝑑 𝑥 .
Without loss of generality assume that 𝑓𝑖𝑛𝑑 𝑥 = 𝑓𝑖𝑛𝑑(𝑝)
𝑑′ 𝑥 > 𝑑 𝑥 can only happen if 𝑓𝑖𝑛𝑑(𝑞) becomes the parent of 𝑓𝑖𝑛𝑑(𝑝).
Proof: Consider any union(𝑝, 𝑞) step (only time at which values changes).
Let 𝑑 𝑥 , 𝑠𝑖𝑧𝑒(𝑥) be the values before the union and 𝑑′ 𝑥 , 𝑠𝑖𝑧𝑒′(𝑥) the values after the union.
For all 𝑥, assume that (∗) is satisfied before the union.
We want to show that 2𝑑′ 𝑥 ≤ 𝑠𝑖𝑧𝑒′(𝑥) afterwards as well.
⇒ 2𝑑(𝑥) ≤ 𝑠𝑖𝑧𝑒 𝑥 = 𝑠𝑖𝑧𝑒 𝑓𝑖𝑛𝑑 𝑝 ≤ 𝑠𝑖𝑧𝑒(𝑓𝑖𝑛𝑑 𝑞 )
⇒ 𝑑′(𝑥) = 𝑑 𝑥 + 1; 𝑠𝑖𝑧𝑒′ 𝑥 = 𝑠𝑖𝑧𝑒 𝑓𝑖𝑛𝑑(𝑥) + 𝑠𝑖𝑧𝑒(𝑓𝑖𝑛𝑑(𝑞))
⇒ 2𝑑′(𝑥) = 2 ⋅ 2𝑑 𝑥 ≤ 2 ⋅ 𝑠𝑖𝑧𝑒 𝑓𝑖𝑛𝑑 𝑝 ≤ 𝑠𝑖𝑧𝑒 𝑓𝑖𝑛𝑑 𝑝 + 𝑠𝑖𝑧𝑒 𝑓𝑖𝑛𝑑 𝑞 = 𝑠𝑖𝑧𝑒′(𝑥)!
Theorem: For any 𝑥 let 𝑑 𝑥 be the depth of 𝑥 in its up-tree and 𝑠𝑖𝑧𝑒(𝑥) the # of nodes in its
up-tree. Then ∗ 2𝑑(𝑥)
≤ 𝑠𝑖𝑧𝑒 𝑥 .
𝑝 𝑞
𝑓𝑖𝑛𝑑(𝑝)
𝑓𝑖𝑛𝑑(𝑞)
𝑠𝑖𝑧𝑒 𝑝 ≤ 𝑠𝑖𝑧𝑒(𝑞)
𝑥
49
Outline
• Union Find
• Introduction
• First version
• Up-trees
• Union by size
• Going further
50
4th version: Adding path compression
The running time can be improved via another trick.
In find(x), first trace the path from 𝑥 to the root.
Let 𝑟 be the root of the tree, and the path from 𝑥 to 𝑟 be 𝑥𝑎1𝑎2 … 𝑎𝑘𝑟.
Run through the path again, this time setting all the id’s (parent pointers) of
𝑥, 𝑎1, 𝑎2 , … , 𝑎𝑘 to be the root 𝑟 .
𝑥
𝑎1
𝑎1
𝑎𝑘
r
𝑎3
𝑥
𝑎1
𝑎1
𝑎𝑘
r
𝑎3
X
X
X
This is called Path compression.
It requires 𝑓𝑖𝑛𝑑(𝑥) to make two
loops. The first to find 𝑟; the
second to walk up from 𝑥 again,
changing all of the id’s.
This will make the trees very
shallow!
51
4th version: Adding path compression
Proposition [Hopcroft-Ullman, Tarjan]
𝑥
𝑎1
𝑎1
𝑎𝑘
r
𝑎3
𝑥
𝑎1
𝑎1
𝑎𝑘
r
𝑎3
X
X
X
Starting from the empty data structure, any sequence of 𝑚 𝑓𝑖𝑛𝑑 operations on 𝑛 objects
makes 𝑶(𝒏 + 𝒎 𝐥𝐨𝐠∗
𝒏) work (array, accesses).
log∗
𝑛 is the iterated logarithm log∗ n = ቊ
0 if n ≤ 1
1 + log∗(log2 n) otherwise
log2 1 = 0
log∗ 2 = 1
log∗ 22 = 2
log∗ 222
= 3
log∗ 2222
= 4
log∗ 22222
= 5
Note that 2222
= 216
= 65536. So 22222
= 265536
You are NEVER going to have 𝑛 > 265536
so, for all practical
applications, log∗
𝑛 ≤ 5
52
4th version: Adding path compression
Proposition [Hopcroft-Ullman, Tarjan]
𝑥
𝑎1
𝑎1
𝑎𝑘
r
𝑎3
𝑥
𝑎1
𝑎1
𝑎𝑘
r
𝑎3
X
X
X
Starting from the empty data structure, any sequence of 𝑚 𝑓𝑖𝑛𝑑 operations on 𝑛 objects
makes 𝑶(𝒏 + 𝒎 𝐥𝐨𝐠∗
𝒏) work (array, accesses).
Starting from the empty data structure, any sequence of 𝑚 𝑓𝑖𝑛𝑑 operations on 𝑛 objects
makes 𝑶(𝒏 + 𝒎 𝛂(𝐦, 𝐧)) work (array, accesses) and that’s the best possible!
[Hopcroft-Ullman, Tarjan] actually proved something even better,
𝛂(𝐦, 𝐧) is the inverse Ackermann function, which grows even slower than log∗
𝑛
https://en.wikipedia.org/wiki/Ackermann_function
https://en.wikipedia.org/wiki/Iterated_logarithm

More Related Content

Similar to learning about union find algorithm lectures (20)

PPTX
Disjoint set / Union Find Data Structure
Log(n) Academy
 
DOCX
Algorithm
nivlayalat
 
PPTX
Implementation of union
rajshreemuthiah
 
PDF
Minimum Spanning Trees Artificial Intelligence
jiraf23341
 
PPTX
Set Operations - Union Find and Bloom Filters
Amrinder Arora
 
PPTX
DISJOINT SETS.pptx
JyoReddy9
 
PPTX
Path compression
DEEPIKA T
 
PPTX
Disjoint sets union, find
subhashchandra197
 
PPT
ee220s02lec10.ppt.........................
AnilKumar914552
 
PPTX
Advanced Algorithms #1 - Union/Find on Disjoint-set Data Structures.
Andrea Angella
 
PDF
Gwt presen alsip-20111201
Yasuo Tabei
 
PDF
Declare Your Language: Constraint Resolution 2
Eelco Visser
 
PPT
Sets and disjoint sets union123
Ankita Goyal
 
PPTX
Disjoint set
DeepikaT13
 
PPT
computer notes - Data Structures - 29
ecomputernotes
 
PDF
Time complexity of union find
Wei (Terence) Li
 
PDF
smtlecture.7
Roberto Bruttomesso
 
PPT
computer notes - Data Structures - 30
ecomputernotes
 
PPT
Computer notes - Analysis of Union
ecomputernotes
 
PDF
Proof of O(log *n) time complexity of Union find (Presentation by Wei Li, Zeh...
Amrinder Arora
 
Disjoint set / Union Find Data Structure
Log(n) Academy
 
Algorithm
nivlayalat
 
Implementation of union
rajshreemuthiah
 
Minimum Spanning Trees Artificial Intelligence
jiraf23341
 
Set Operations - Union Find and Bloom Filters
Amrinder Arora
 
DISJOINT SETS.pptx
JyoReddy9
 
Path compression
DEEPIKA T
 
Disjoint sets union, find
subhashchandra197
 
ee220s02lec10.ppt.........................
AnilKumar914552
 
Advanced Algorithms #1 - Union/Find on Disjoint-set Data Structures.
Andrea Angella
 
Gwt presen alsip-20111201
Yasuo Tabei
 
Declare Your Language: Constraint Resolution 2
Eelco Visser
 
Sets and disjoint sets union123
Ankita Goyal
 
Disjoint set
DeepikaT13
 
computer notes - Data Structures - 29
ecomputernotes
 
Time complexity of union find
Wei (Terence) Li
 
smtlecture.7
Roberto Bruttomesso
 
computer notes - Data Structures - 30
ecomputernotes
 
Computer notes - Analysis of Union
ecomputernotes
 
Proof of O(log *n) time complexity of Union find (Presentation by Wei Li, Zeh...
Amrinder Arora
 

Recently uploaded (20)

PDF
Rethinking Security Operations - SOC Evolution Journey.pdf
Haris Chughtai
 
PDF
Chris Elwell Woburn, MA - Passionate About IT Innovation
Chris Elwell Woburn, MA
 
PPTX
Building and Operating a Private Cloud with CloudStack and LINBIT CloudStack ...
ShapeBlue
 
PDF
Ampere Offers Energy-Efficient Future For AI And Cloud
ShapeBlue
 
PPTX
Top iOS App Development Company in the USA for Innovative Apps
SynapseIndia
 
PDF
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
PDF
Persuasive AI: risks and opportunities in the age of digital debate
Speck&Tech
 
PDF
Smart Air Quality Monitoring with Serrax AQM190 LITE
SERRAX TECHNOLOGIES LLP
 
PDF
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
PPTX
Top Managed Service Providers in Los Angeles
Captain IT
 
PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PDF
July Patch Tuesday
Ivanti
 
PDF
Apache CloudStack 201: Let's Design & Build an IaaS Cloud
ShapeBlue
 
PDF
Building Resilience with Digital Twins : Lessons from Korea
SANGHEE SHIN
 
PDF
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
PPTX
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
PDF
Women in Automation Presents: Reinventing Yourself — Bold Career Pivots That ...
DianaGray10
 
PDF
CloudStack GPU Integration - Rohit Yadav
ShapeBlue
 
PDF
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
PPT
Interview paper part 3, It is based on Interview Prep
SoumyadeepGhosh39
 
Rethinking Security Operations - SOC Evolution Journey.pdf
Haris Chughtai
 
Chris Elwell Woburn, MA - Passionate About IT Innovation
Chris Elwell Woburn, MA
 
Building and Operating a Private Cloud with CloudStack and LINBIT CloudStack ...
ShapeBlue
 
Ampere Offers Energy-Efficient Future For AI And Cloud
ShapeBlue
 
Top iOS App Development Company in the USA for Innovative Apps
SynapseIndia
 
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
Persuasive AI: risks and opportunities in the age of digital debate
Speck&Tech
 
Smart Air Quality Monitoring with Serrax AQM190 LITE
SERRAX TECHNOLOGIES LLP
 
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
Top Managed Service Providers in Los Angeles
Captain IT
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
July Patch Tuesday
Ivanti
 
Apache CloudStack 201: Let's Design & Build an IaaS Cloud
ShapeBlue
 
Building Resilience with Digital Twins : Lessons from Korea
SANGHEE SHIN
 
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
Women in Automation Presents: Reinventing Yourself — Bold Career Pivots That ...
DianaGray10
 
CloudStack GPU Integration - Rohit Yadav
ShapeBlue
 
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
Interview paper part 3, It is based on Interview Prep
SoumyadeepGhosh39
 
Ad

learning about union find algorithm lectures

  • 1. CICS 210 Data Structures Union-Find V1 - 11/24/2024 MJ Golin CICS Fall 2024
  • 2. 2 Outline • Union Find • Introduction • First version • Up-trees • Union by size • Going further
  • 3. 3 The Union Find Problem • We’re now returning to graph connectivity. • Will see an algorithm for being able to answer graph connectivity updates quickly. • This will actually be an algorithm for set maintenance (under insertions). 1 9 3 5 4 8 7 6 11 10 2 12 13 Recall graph connectivity (undirected graphs). • Two vertices in a graph are connected if there exists a path from one to the other. • A connected component is a maximal subgraph in which every vertex is connected to every other vertex. Graph to the left has 3 connected components.
  • 4. 4 The Union Find Problem • We’re now returning to graph connectivity • Will see an algorithm for being able to answer graph connectivity updates quickly • This will actually be an algorithm for set maintenance (under insertions) 1 9 3 5 4 8 7 6 11 10 2 12 13 Connected(a,b): query that returns true if and only if a and b are in the same connected component. A B C Find(a): query that returns the name of the component containing a. Find(3) = Find(6) = A; Find(2) = C
  • 5. 5 The Union Find Problem Note that Connected(a,b) is only asking whether a,b are in the same connected component set. A Union (a,b) will merge the two sets if a,b are in different sets. If they’re in the same set it will do nothing We stated this “connected” problem in a graph but remember, graphs model relationships. So this problem can be applied to anything that can be modeled by a relationship graph, e.g., • Pixels in a digital photo. • Computers in a network. • Friends in a social network. • Transistors in a computer chip. • Elements in a mathematical set. • Variable types in a program. We should also point out that connected components in graphs model “equivalence relations”. So we’re really trying to figure out if two item are equivalent to each other in an equivalence relation. 1 9 3 5 4 8 7 6 11 10 2 12 13
  • 6. 6 The Union Find Problem Suppose that we start with no edges. The problem is to add edges and keep track of them in such a way that we can always answer Connected(a,b) efficiently. Union (a,b) will denote adding the edge (a,b). 1 9 3 5 4 8 7 6 Connected(4,7)? Union(4,9) 𝐹𝑎𝑙𝑠𝑒 𝑇𝑟𝑢𝑒 Union(3,5) Connected(4,8)? 𝐹𝑎𝑙𝑠𝑒 Union(3,8) Connected(5,8)? Connected(1,4)? 𝐹𝑎𝑙𝑠𝑒 Union(1,9) Union(9,5) Connected(4,8)? 𝑇𝑟𝑢𝑒 Union(1,3)
  • 7. 7 The Union Find Problem Note that Connected(a,b) is only asking whether a,b are in the same connected component set. A Union (a,b) will merge the two sets if a,b are in different sets. If they’re in the same set it will do nothing 1 9 3 5 4 8 7 6 Connected(4,7)? Union(4,9) 𝐹𝑎𝑙𝑠𝑒 𝑇𝑟𝑢𝑒 Union(3,5) Connected(4,8)? 𝐹𝑎𝑙𝑠𝑒 Union(3,8) Connected(5,8)? Connected(1,4)? 𝐹𝑎𝑙𝑠𝑒 Union(1,9) Union(9,5) Connected(4,8)? 𝑇𝑟𝑢𝑒 Union(1,3) 1 3 {4} 5 6 7 8 {9} 1 3 {4,9} 5 6 7 8 1 3,5 {4,9} 6 7 8 1 3,5,8 {4,9} 6 7 3,5,8 {1,4,9} 6 7 1,3,5,8,4,9 6 7 No Change!
  • 8. 8 The Union Find Problem Note that Connected(a,b) is only asking whether a,b are in the same connected component set. A Union (a,b) will merge the two sets if a,b are in different sets. If they’re in the same set it will do nothing 1 9 3 5 4 8 7 6 We know how to find connected components in time linear in 𝑂(𝑉 + 𝐸) but we don’t want to have to redo the entire algorithm every time we change the graph by adding an edge. We’re now going to develop an algorithm for doing this more efficiently. Our algorithm will be for set maintenance.
  • 9. 9 The Union Find Problem Assume that out items (vertices) are integers on [0, 𝑛 − 1] Want to support • union(p, q) - add an edge between p and q, placing them into the same connected component • find(p) - return the component id (an int) for the vertex p • connected(p, q) - true if and only if p and q are in the same component Every item will have an (integer) id that is the name of the component it belongs. Since connected(p, q) == (find(p) == find(q)) it is unnecessary to derive it further public interface UnionFind { int find(int p); void union(int p, int q); boolean connected(int p, int q); }
  • 10. 10 Outline • Union Find • Introduction • First version • Up-trees • Union by size • Going further
  • 11. 11 First Simple Version 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 𝑖𝑑[𝑖] 0 1 1 0 2 1 • union(p, q) – change all entries whose id equals 𝑖𝑑[𝑝] to 𝑖𝑑[𝑞] • find(p) – return 𝑖𝑑[𝑝] union(2, 0) 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 𝑖𝑑[𝑖] 0 0 0 0 2 0
  • 12. 12 public class QuickFindUF implements UnionFind { private int[] id; public QuickFindUF(int N) { id = new int[N]; for (int i = 0; i < N; i++) { id[i] = i; // each in own component to start } } public int find(int p) { return id[p]; } public void union(int p, int q) { int pid = id[p]; int qid = id[q]; for (int i = 0; i < id.length; i++) { if (id[i] == pid) { id[i] = qid; } } } public boolean connected(int p, int q) { return find(p) == find(q); } } Initialize by having every item in its own component (setting id[i]=i) find(p) just returns p’s ID union(p,q) sets the id of everyone in same set as p to id[q] connected(p,q) returns whether p and q are in the same set
  • 13. 13 First Simple Version 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 𝑖𝑑[𝑖] 0 1 1 0 2 1 • union(p, q) – change all entries whose id equals 𝑖𝑑[𝑝] to 𝑖𝑑[𝑞] • find(p) – return 𝑖𝑑[𝑝] union(2, 0) 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 𝑖𝑑[𝑖] 0 0 0 0 2 0 Bad running time. Can take 𝑂 𝑉 time per step Sequence union(0,1) union(1,2) union(2,3) … union(n-2,n-1) would take Θ 𝑛2 time.
  • 14. 14 Outline • Union Find • Introduction • First version • Up-trees • Union by size • Going further
  • 15. 15 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 3 2 9 3 9 5 6 2 9 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖; 0 1 2 3 4 5 6 7 8 9 • Items are decomposed into trees. • 𝑖𝑑[𝑖] is parent of 𝑖 in its tree • root 𝑖 is identified by 𝑖𝑑 𝑖 = 𝑖
  • 16. 16 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 3 2 9 3 9 5 6 2 9 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖; find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝. Example: 𝑓𝑖𝑛𝑑 7 = 𝑓𝑖𝑛𝑑 2 = 𝑓𝑖𝑛𝑑 9 = 9 𝑓𝑖𝑛𝑑 0 = 𝑓𝑖𝑛𝑑 3 = 3 𝑓𝑖𝑛𝑑 5 = 5 0 1 2 3 4 5 6 7 8 9
  • 17. 17 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 3 2 9 3 9 5 6 2 9 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖; union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑 𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞). 0 1 2 3 4 5 6 7 8 9 Example: 𝑢𝑛𝑖𝑜𝑛(0,1) X X 9 Sets 𝑖𝑑 3 = 𝑓𝑖𝑛𝑑 1 = 9
  • 18. 18 Outline • Union Find • Introduction • First version • Up-trees • Union by size • Going further
  • 19. 19 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 0 1 2 3 4 5 6 7 8 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖; • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝. • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑 𝑝 = 𝑓𝑖𝑛𝑑 𝑞 . 0 1 2 3 4 5 6 7 8 9
  • 20. 20 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 0 1 2 3 4 5 6 7 8 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(1,2) • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 21. 21 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 0 2 2 3 4 5 6 7 8 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(1,2) Now Find(1)=Find(2)=2 • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 22. 22 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 0 2 2 3 4 5 6 7 8 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(7,2) • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 23. 23 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 0 2 2 3 4 5 6 2 8 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(7,2) Now Find(1)=Find(2)=Find(7)=2 • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 24. 24 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 0 2 2 3 4 5 6 2 8 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(8,9) • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 25. 25 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 0 2 2 3 4 5 6 2 9 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(8,9) Now Find(8)=Find(9)=9 • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 26. 26 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 0 2 2 3 4 5 6 2 9 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(7,8) This will set 𝑖𝑑 𝑓𝑖𝑛𝑑 7 = 𝑖𝑑 𝑓𝑖𝑛𝑑 8 𝑖𝑑 2 = 𝑖𝑑 9 = 9 • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 27. 27 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 0 2 9 3 4 5 6 2 9 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(7,8) • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 28. 28 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 0 2 9 3 4 5 6 2 9 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(0,3) • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 29. 29 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 3 2 9 3 4 5 6 2 9 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(0,3) • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 30. 30 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 3 2 9 3 4 5 6 2 9 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(8,2) Since Find(8)=Find(2)=9 this does nothing • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 31. 31 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 3 2 9 3 4 5 6 2 9 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(4,7) Sets id[4]=Find(7)=9 • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 32. 32 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 3 2 9 3 9 5 6 2 9 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(4,7) Sets id[4]=Find(7)=9 • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 33. 33 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 3 2 9 3 9 5 6 2 9 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(1,4) Since Find(1)=Find(4)=9 this does nothing • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 34. 34 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 3 2 9 3 9 5 6 2 9 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(0,5) • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 35. 35 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 3 2 9 5 9 5 6 2 9 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(0,5) • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 36. 36 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 3 2 9 5 9 5 6 2 9 9 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(7,6) • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 37. 37 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 3 2 9 5 9 5 6 2 9 6 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(7,6) • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 38. 38 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 3 2 9 5 9 5 6 2 9 6 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(2,0) • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 39. 39 2nd version: Up trees 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 3 2 9 5 9 5 5 2 9 6 7 6 8 9 Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝 Sets (items in the same component) will be represented by up-trees. Every item will start in its component, with 𝑖𝑑 𝑝 = 𝑝. In the general scenario, the items in a component will be stored the same up-tree. 𝑖𝑑[𝑖] will be the name of another item in the same set “above it” in the up-tree. 0 1 2 3 4 5 6 7 8 9 Union(2,0) • find(p) – return 𝑖𝑑[𝑞] where 𝑞 is the root of the up-tree containing 𝑝 • union(p, q) – if 𝑝 and 𝑞 are in different sets, merge the sets by setting the id of the root of the up-tree containing 𝑝 to be the root of the up-tree containing 𝑞 i.e., 𝑖𝑑[𝑓𝑖𝑛𝑑(𝑝) = 𝑓𝑖𝑛𝑑(𝑞) The highest item in an up-tree is its root. The root 𝑖 of the up-tree has 𝑖𝑑 𝑖 = 𝑖;
  • 40. 40 public class QuickUnion implements UnionFind { private int[] id; public QuickUnion(int N) { id = new int[N]; for (int i = 0; i < N; i++) { id[i] = i; // each in own component to start } } public int find(int p) { while (p != id[p]) { p = id[p]; } return p; } public void union(int p, int q) { id[find(p)] = find(q); } public boolean connected(int p, int q) { return find(p) == find(q); } } Same as before Returns the root of the tree that contains p. Does this by walking up parents in tree until it finds the root, which is the node satisfying 𝑖 = 𝑖𝑑 𝑖 . union(p,q) points root of tree containing p to root of tree containing q. Note: If find[p]=find[q] it points root to itself, not changing anything.
  • 41. 41 Outline • Union Find • Introduction • First version • Up-trees • Union by size • Going further
  • 42. 42 3rd version: Up trees with Union by size Suppose we did union(0,1) union(0,2) union(0,3) … union(0,n-1) What would happen? 0 1 0 1 2 0 1 2 3 0 1 2 3 𝑛 − 2 n − 1 How much time would this require? After the first 𝑖 unions, it takes 𝑖 − 1 steps to implement 𝑓𝑖𝑛𝑑 0 , so total work is σ𝑖=1 𝑛−1 𝑖 − 1 = Θ(𝑛2) The problem is that the trees built are long and narrow. Can you see a way to fix this?
  • 43. 43 3rd version: Union by size The problem was that we made the root of a small tree (one node) the parent of the larger tree. One fix (that works) is to look at the size of the trees and make the root of the LARGER one the root of the combined tree. As an example, consider this scenario we saw earlier 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 0 2 2 3 4 5 6 2 9 9 7 6 8 9 0 1 2 3 4 5 6 7 8 9 As an example, consider this scenario we saw earlier We were asked to do Union(7,8) so we pointed 2 to 9 Since we are doing Union by size, we would point 9 to 2 instead.
  • 44. 44 3rd version: Union by size The problem was that we made the root of a small tree (one node) the parent of the larger tree. One fix (that works) is to look at the size of the trees and make the root of the LARGER one the root of the combined tree. As an example, consider this scenario we saw earlier 1 2 3 5 4 0 𝑖 0 1 2 3 4 5 6 7 8 9 𝑖𝑑[𝑖] 0 2 2 3 4 5 6 2 9 2 7 6 8 9 0 1 2 3 4 5 6 7 8 9 As an example, consider this scenario we saw earlier We were asked to do Union(7,8) so we pointed 2 to 9 Since we are doing Union by size, we would point 9 to 2 instead.
  • 45. 45 3rd version: Union by size (Implementation) The problem was that we made the root of a small tree (one node) the parent of the larger tree. One fix (that works) is to look at the size of the trees and make the root of the LARGER one the root of the combined tree. For each node: Also keep a size variable sz[i]. sz[i] will be the number of nodes in the tree rooted at i (only used if 𝑖 is the root of its up-tree) public void union(int p, int q) { int i = find(p); int j = find(q); if (i == j) return; if (sz[i] < sz[j]) { id[i] = j; sz[j] += sz[i]; } else { id[j] = i; sz[i] += sz[j]; } } i, j are the roots of the two trees If tree rooted at i is larger, make i the root Otherwise, make j the root the roots of the two trees In both cases update the size of the root of the combined tree to reflect thatit now contains everything
  • 46. 46 3rd version: Up trees with Union by size Suppose we now redo our quadratic bad case using union by size union(0,1) union(0,2) union(0,3) … union(0,n-1) Then we would get 0 1 0 1 2 3 0 2 3 𝑛 − 2 n − 1 This only takes 𝑂 1 time per step. We’ll now see that, when using union by size, the trees never get higher than log2 𝑛, so no find or union step requires more than 𝑂(log 𝑛) time. 0 1 2 …
  • 47. 47 3rd version: Up trees with Union by size Theorem: For any 𝑥 let 𝑑 𝑥 be the depth of 𝑥 in its up-tree and 𝑠𝑖𝑧𝑒(𝑥) the # of nodes in its up-tree. Then 2𝑑(𝑥) ≤ 𝑠𝑖𝑧𝑒 𝑥 . Let 𝑛 be the total # of nodes. This means that every union and find operation takes 𝑂(log 𝑛) time Assume theorem is true Since, for every 𝑥, 2𝑑(𝑥) ≤ 𝑠𝑖𝑧𝑒 𝑥 ≤ 𝑛, we get 𝑑 𝑥 ≤ log2 𝑛 , which means that 𝑓𝑖𝑛𝑑(𝑥) never takes more than log2 𝑛 steps. In particular, 𝑛 operations takes 𝑂 𝑛 𝑙𝑜𝑔 𝑛 time, a big improvement from the 𝑂(𝑛2 ) of the previous version.
  • 48. 48 3rd version: Up trees with Union by size • At start, for every node 𝑥, 𝑑(𝑥) = 0 and 𝑠𝑖𝑧𝑒 𝑥 = 1, so 2𝑑(𝑥) = 1 = 𝑠𝑖𝑧𝑒 𝑥 . • Since 𝑑 𝑥 ≤ 𝑑′(𝑥) and 𝑠𝑖𝑧𝑒 𝑥 ≤ 𝑠𝑖𝑧𝑒′ 𝑥 , this can only be violated if 𝑑′ 𝑥 > 𝑑 𝑥 . Without loss of generality assume that 𝑓𝑖𝑛𝑑 𝑥 = 𝑓𝑖𝑛𝑑(𝑝) 𝑑′ 𝑥 > 𝑑 𝑥 can only happen if 𝑓𝑖𝑛𝑑(𝑞) becomes the parent of 𝑓𝑖𝑛𝑑(𝑝). Proof: Consider any union(𝑝, 𝑞) step (only time at which values changes). Let 𝑑 𝑥 , 𝑠𝑖𝑧𝑒(𝑥) be the values before the union and 𝑑′ 𝑥 , 𝑠𝑖𝑧𝑒′(𝑥) the values after the union. For all 𝑥, assume that (∗) is satisfied before the union. We want to show that 2𝑑′ 𝑥 ≤ 𝑠𝑖𝑧𝑒′(𝑥) afterwards as well. ⇒ 2𝑑(𝑥) ≤ 𝑠𝑖𝑧𝑒 𝑥 = 𝑠𝑖𝑧𝑒 𝑓𝑖𝑛𝑑 𝑝 ≤ 𝑠𝑖𝑧𝑒(𝑓𝑖𝑛𝑑 𝑞 ) ⇒ 𝑑′(𝑥) = 𝑑 𝑥 + 1; 𝑠𝑖𝑧𝑒′ 𝑥 = 𝑠𝑖𝑧𝑒 𝑓𝑖𝑛𝑑(𝑥) + 𝑠𝑖𝑧𝑒(𝑓𝑖𝑛𝑑(𝑞)) ⇒ 2𝑑′(𝑥) = 2 ⋅ 2𝑑 𝑥 ≤ 2 ⋅ 𝑠𝑖𝑧𝑒 𝑓𝑖𝑛𝑑 𝑝 ≤ 𝑠𝑖𝑧𝑒 𝑓𝑖𝑛𝑑 𝑝 + 𝑠𝑖𝑧𝑒 𝑓𝑖𝑛𝑑 𝑞 = 𝑠𝑖𝑧𝑒′(𝑥)! Theorem: For any 𝑥 let 𝑑 𝑥 be the depth of 𝑥 in its up-tree and 𝑠𝑖𝑧𝑒(𝑥) the # of nodes in its up-tree. Then ∗ 2𝑑(𝑥) ≤ 𝑠𝑖𝑧𝑒 𝑥 . 𝑝 𝑞 𝑓𝑖𝑛𝑑(𝑝) 𝑓𝑖𝑛𝑑(𝑞) 𝑠𝑖𝑧𝑒 𝑝 ≤ 𝑠𝑖𝑧𝑒(𝑞) 𝑥
  • 49. 49 Outline • Union Find • Introduction • First version • Up-trees • Union by size • Going further
  • 50. 50 4th version: Adding path compression The running time can be improved via another trick. In find(x), first trace the path from 𝑥 to the root. Let 𝑟 be the root of the tree, and the path from 𝑥 to 𝑟 be 𝑥𝑎1𝑎2 … 𝑎𝑘𝑟. Run through the path again, this time setting all the id’s (parent pointers) of 𝑥, 𝑎1, 𝑎2 , … , 𝑎𝑘 to be the root 𝑟 . 𝑥 𝑎1 𝑎1 𝑎𝑘 r 𝑎3 𝑥 𝑎1 𝑎1 𝑎𝑘 r 𝑎3 X X X This is called Path compression. It requires 𝑓𝑖𝑛𝑑(𝑥) to make two loops. The first to find 𝑟; the second to walk up from 𝑥 again, changing all of the id’s. This will make the trees very shallow!
  • 51. 51 4th version: Adding path compression Proposition [Hopcroft-Ullman, Tarjan] 𝑥 𝑎1 𝑎1 𝑎𝑘 r 𝑎3 𝑥 𝑎1 𝑎1 𝑎𝑘 r 𝑎3 X X X Starting from the empty data structure, any sequence of 𝑚 𝑓𝑖𝑛𝑑 operations on 𝑛 objects makes 𝑶(𝒏 + 𝒎 𝐥𝐨𝐠∗ 𝒏) work (array, accesses). log∗ 𝑛 is the iterated logarithm log∗ n = ቊ 0 if n ≤ 1 1 + log∗(log2 n) otherwise log2 1 = 0 log∗ 2 = 1 log∗ 22 = 2 log∗ 222 = 3 log∗ 2222 = 4 log∗ 22222 = 5 Note that 2222 = 216 = 65536. So 22222 = 265536 You are NEVER going to have 𝑛 > 265536 so, for all practical applications, log∗ 𝑛 ≤ 5
  • 52. 52 4th version: Adding path compression Proposition [Hopcroft-Ullman, Tarjan] 𝑥 𝑎1 𝑎1 𝑎𝑘 r 𝑎3 𝑥 𝑎1 𝑎1 𝑎𝑘 r 𝑎3 X X X Starting from the empty data structure, any sequence of 𝑚 𝑓𝑖𝑛𝑑 operations on 𝑛 objects makes 𝑶(𝒏 + 𝒎 𝐥𝐨𝐠∗ 𝒏) work (array, accesses). Starting from the empty data structure, any sequence of 𝑚 𝑓𝑖𝑛𝑑 operations on 𝑛 objects makes 𝑶(𝒏 + 𝒎 𝛂(𝐦, 𝐧)) work (array, accesses) and that’s the best possible! [Hopcroft-Ullman, Tarjan] actually proved something even better, 𝛂(𝐦, 𝐧) is the inverse Ackermann function, which grows even slower than log∗ 𝑛 https://en.wikipedia.org/wiki/Ackermann_function https://en.wikipedia.org/wiki/Iterated_logarithm