Improvement 1: weighting
weighted quick union
- modify quick-union to avoid tall trees
- keep track of size of each tree(number of each objects)
- balance by linking root of smaller tree to the root of larger tree(larger tree on top, small tree goes below)
No item is too far from the root of its component!!!
Implementation
Data Structure
same as quick-union, but maintain extra array sz[i] to count number of objects in the tree rooted at i.
Find( p, q )
Identical to quick-union
return root( p ) == root( q );
Union( p, q )
- link root of smaller trees to larger trees
- update sz[] array
int i = root( p ),
j = root( 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];
}
Analysis
Running Time
- Find: proportional to the depth of p and q
- Union: constant time given roots
Proposition
Depths of any node x is at most lgN(base 2)
Algorithm | Initialize | Union | Connected |
---|---|---|---|
quick-find | O(N) | O(N) | O(1) |
quick-union | O(N) | O(N) | O(N) |
weighted QU | O(N) | O(logN) | O(logN) |
Improvement 2: Path Compression
Just after computing the root of p, set the each examined node to point to that root.
Implementation
- Two-pass implementation: second loop to set the id[] of each examined to the root
- One-pass variant: make every node in path points to its grandparent(halving path length)
private int root( int i )
{
while( i != id[i] )
{
id[i] = id[id[i]];
i = id[i];
}
return i;
}
Keep the tree almost flat!!
Analysis(weighted QU with path compression)
Proposition
Starting from and empty data structure, any sequence of m union-find ops on N objects makes
≤c(N+Mlog∗N)
array access.(near linear)
Cost Comparison
There is no linear algorithm for Union-Find ops, but WQUPC is linear in most cases.