1.Problem
Quick Union is a useful method to solve the dynamic connectivity problem, which can also be solved by depth-first search or breadth-first search.
2.Quick Union
Data structure
Integer array id[] of length N
id[i] is the parent of i, and to find the root of i, you are supposed to keep going until the parent doesn't change.
API
Connected(p,q) To judge whether p and q have the same root. Find(p) To find the root of p. Union(p,q) Set the id of p's root to the id of q's root. Code
int find(int p){ while(p!=id[p]){ p = id[p]; } return p; } bool connected(int p,int q){ return find(p)==find(q); } void Union(int p,int q){ int idp = find(p); int idq = find(q); if(connected(p,q)){ return; } id[idp] = idq; count --; }
3.Improvements
3.1 Weighting quick union
Idea
Balance by linking root of smaller tree to the root of lager tree
Data structure
Maintain extra array sz[] to count number of objects in the tree.
Code
void Union(int p,int q){ int idp = find(p); int idq = find(q); if(connected(p,q)){ return; } if(sz[idp]<sz[idq]){ id[idp] = idq; sz[idq] += sz[idp]; }else{ id[idq] = idp; sz[idp] += sz[idq]; } count --; }
Summary
Through this improvement, run time can be reduced sharply from 2984ms to 52ms when the quick union is applied the 130th problem in the leetcode.
3.2 Path compression
Idea
When finding the node, just after computing the root of p, set the id[] of each examined node to point to that root.
Code
int find(int p){ int temp = p; while(p!=id[p]){ p = id[p]; } id[temp] = p; return p; }