A Disjoint Set is a data structure used to maintain a collection of non-overlapping sets. It efficiently keeps track of which elements belong to the same group and supports operations for finding an element's group and combining two separate groups.
The structure is commonly known as Disjoint Set Union (DSU) or Union-Find. It is especially useful when a program repeatedly needs to determine whether two elements belong to the same connected group and merge groups as relationships are discovered.
What Is a Disjoint Set?
A disjoint set collection contains groups where no element belongs to more than
one group. For example, suppose we have the elements
1, 2, 3, 4, 5, 6. They could initially be represented as six separate
sets:
{1} {2} {3} {4} {5} {6}
If elements 1 and 2 are connected, their sets can be combined:
{1, 2} {3} {4} {5} {6}
Later, if 2 and 3 become connected, the first group can be merged with the group containing 3:
{1, 2, 3} {4} {5} {6}
A Disjoint Set data structure performs these grouping operations efficiently without repeatedly rebuilding the complete collection.
Disjoint Set vs Union-Find
Disjoint Set, Disjoint Set Union (DSU), and Union-Find commonly refer to the same family of data structures and algorithms.
The name Union-Find comes directly from its two primary operations:
union, which combines two sets, and find, which determines
the representative of the set containing an element.
Why Use a Disjoint Set?
A Disjoint Set is useful when groups continuously change because separate elements become connected. Instead of performing an expensive search through all existing relationships after every change, DSU maintains a compact representation of the groups.
This makes it particularly useful for connectivity problems, where the main question is whether two elements belong to the same component.
Core Operations of Disjoint Set
A typical Disjoint Set implementation provides three fundamental operations:
- Make Set: Creates a new set containing an individual element.
- Find: Determines the representative of the set containing an element.
- Union: Combines two sets into one set.
Make Set
Initially, every element can be placed into its own independent set. Each element acts as its own representative.
1 → 1
2 → 2
3 → 3
4 → 4
Find
The find operation identifies the representative, or root, of the set
containing a particular element. Elements belonging to the same set eventually
lead to the same representative.
Union
The union operation combines the sets containing two specified elements.
If both elements already belong to the same set, no structural change is required.
How a Disjoint Set Is Represented
A common implementation represents each set as a tree. Every element stores a reference to its parent, and the root of the tree acts as the representative of the set.
1
/ \
2 3
/
4
In this example, element 1 is the root and therefore represents the set. Elements 2, 3, and 4 belong to the same set because following their parent references eventually reaches 1.
Parent Array Representation
In array-based implementations, a parent array can store the parent
relationship for every element. If an element is its own parent, it represents
the root of its set.
parent[1] = 1
parent[2] = 1
parent[3] = 1
parent[4] = 2
Following the parent references from 4 gives
4 → 2 → 1, so 1 is the representative of the set containing 4.
Example of Union Operations
Suppose we start with five independent sets:
{1} {2} {3} {4} {5}
Performing union(1, 2) creates one group:
{1, 2} {3} {4} {5}
Then union(2, 3) merges the set containing 2 with the set containing 3:
{1, 2, 3} {4} {5}
A later union(4, 5) creates another group:
{1, 2, 3} {4, 5}
Checking Whether Two Elements Are Connected
One of the most useful operations of DSU is checking whether two elements belong
to the same set. Two elements are connected in the Disjoint Set representation
when their find operations return the same representative.
find(1) === find(3)
If both operations return the same root, the elements belong to the same connected component. Otherwise, they are currently in different sets.
Union by Rank and Path Compression
A basic Union-Find implementation can become inefficient if its trees become too tall. Two important optimizations solve this problem: union by rank and path compression.
Union by rank attaches the shorter tree below the taller tree. Path compression
changes parent references during a find operation so that visited
elements point much closer to the root.
These optimizations are covered in more detail in the related topics Union-Find, Path Compression, and Union by Rank.
Disjoint Set Time Complexity
With both path compression and union by rank or size, a sequence of
m operations on n elements has an amortized complexity
of O(m α(n)), where α(n) is the inverse Ackermann
function.
The inverse Ackermann function grows extremely slowly. For practical input sizes, it behaves almost like a constant, which makes optimized Union-Find operations extremely efficient.
| Operation | Basic Implementation | Optimized DSU |
|---|---|---|
| Make Set | O(1) | O(1) |
| Find | Can approach O(n) | Amortized O(α(n)) |
| Union | Can approach O(n) | Amortized O(α(n)) |
Applications of Disjoint Set
Disjoint Set is useful whenever elements are gradually combined into groups and the application needs to answer connectivity questions efficiently.
- Detecting connected components in graphs
- Detecting cycles in undirected graphs
- Kruskal's Minimum Spanning Tree algorithm
- Network connectivity problems
- Grouping related objects
- Dynamic connectivity problems
- Clustering and component management
Disjoint Set for Connected Components
Consider a graph where edges are added over time. Initially, every vertex can be
considered an independent component. Whenever an edge connects two vertices,
their sets can be merged using the union operation.
At any point, calling find for two vertices tells us whether they
belong to the same connected component.
Disjoint Set and Cycle Detection
DSU can also be used to detect cycles in an undirected graph. For every edge
connecting vertices u and v, first check whether
find(u) and find(v) return the same representative.
If they already belong to the same set, adding the edge would connect vertices
that are already connected, indicating a cycle. Otherwise, their sets can be
merged using union.
Disjoint Set vs Other Data Structures
A Disjoint Set is specialized for maintaining groups that only need to be merged and queried for connectivity. It is not intended to replace general-purpose structures such as arrays, hash tables, linked lists, or search trees.
If an application needs to retrieve arbitrary values, maintain sorted order, or perform frequent insertion and deletion of individual records, another data structure may be more appropriate.
Common Disjoint Set Mistakes
- Confusing an element with the representative of its set.
- Calling union directly on elements without first finding their roots.
- Forgetting path compression in performance-sensitive implementations.
- Building unnecessarily tall trees during union operations.
- Using DSU for problems that require more detailed graph traversal or ordering information.
Disjoint Set Example in JavaScript
The following implementation demonstrates the core Union-Find idea using a parent array. It includes path compression and union by rank so that the resulting structure remains efficient for a large sequence of operations.
Key Takeaways
- Disjoint Set maintains a collection of non-overlapping sets.
- It is also known as Disjoint Set Union or Union-Find.
- The main operations are Make Set, Find, and Union.
- Each set can be represented as a tree whose root is its representative.
- Path compression makes Find operations faster.
- Union by rank or size prevents unnecessarily tall trees.
- Optimized DSU operations have near-constant amortized complexity.
- DSU is widely used for connectivity, cycle detection, and minimum spanning tree problems.