Union and Find
This page provides introduction to union and find data structure.
Overview
Union and find is a data structure used to efficiently manage a collection of disjoint sets and supports two main operations:
- Union: Merges two sets into one.
- Find: Determines which set a particular element is in.
Build Union and Find
Let's build a union and find data structure for below disjoint group:
We represent all relationships in disjoint groups using the union and find data structure. To achieve this, we first determine the parent of each node by tracing the values in the array until we find a node that points to itself. Once the parents are identified, we unify the groups by assigning the parent of one node to the other.
Initially, we set the parent of each node to itself.
Node is connected to node . The parent of is , and the parent of is . Therefore we update the parent of to be to represent the connection.
Node is connected to node . The parent of is , and the parent of is . Therefore we update the parent of to be to represent the connection.
Node is connected to node . The parent of is , and the parent of is , here no updates are required and node and belong to same group.
Node is connected to node . The parent of is , and the parent of is . Therefore we update the parent of to be to represent the connection.
Similarly, we explore all connections from node and to get the same result as above image.
Next we explore all connections from node . The parent of is , and the parent of is . Therefore we update the parent of to be to represent the connection.
Similarly, we explore all the connections from node to get the same result as above image.
Finally, we visit node , which has no connections, and our union-find data structure is complete, representing disjoint groups.
- Java
class UnionAndFind {
int[] parentArr;
UnionAndFind(int nodes) {
this.parentArr = new int[nodes];
for(int i = 0; i < nodes; i++) {
parentArr[i] = i;
}
}
public void union(int from, int to) {
int fromParent = find(from);
int toParent = find(to);
if(fromParent != toParent) parentArr[fromParent] = toParent;
}
public int find(int node) {
if(parentArr[node] == node) return node;
int parent = parentArr[node];
/**
* Path compression: Since we have already calculated the parent for this node,
* we can directly update it in the parent array.
* This helps reduce the time required for future queries.
*/
return parentArr[parent] = find(parent);
}
}
Complexity
Let's say there are elements in an array.
Time Complexity
The time complexity for find is:
Where, is the inverse Ackermann function.
The Ackermann function grows extremely slowly, and for practical purposes, is close to a constant value Thus, the find operation is nearly constant time in practice for most cases.
It requires at most one find operation for each of the two sets being merged therefore the time complexity for union is:
Space Complexity
The space is required to store the parent pointers of each element, therefore space complexity is: