The Functionality
有时候,我们需要把相似的元素 group到一起。而每一组的元素是没有区别的,i.e. evey member of a group can be a representative (怎么感觉和数学里面的 quotient set串戏了)。举个例子:
Odd = {1,3,5,…}
Even = {2,4,6…}
在这里面,Odd的 representative可以是任何奇数。
如果我们用一颗颗tree来表示这些元素,那就差不多是 Union-and-Find Forest了。
在这里插入图片描述
Union-Find Data Structure 的操作有:
- Find(x): returns the root / cluster-id of the element x
- Union(x, y): merge two clusters / trees
Complexity Analysis
显然,如果我们只是单纯地把元素一个一个像吃烧烤一样串起来,Find(x)的复杂度将是 O(n)。但是如果我们采用两种优化办法,则可以达到均摊复杂度 O(1) *
- Path Compression: make the tree flat.
- Union by rank: merge the cluster with lower rank to the higher one.
具体来说, path compression就是在 call Find(x)的时候,顺便将元素的 parent改为 root。上图如果使用 Find(8),就会将 8的 parent改为1.
Union by rank的目的也是为了尽可能减小 Find的耗时。Ranks 可以看做是对混乱度的一个measure
Pseudo Code
class UnionFindSet {
function UnionFindSet(n) {
parents = [1,2,...,n]
ranks = [0,...0] (n zeros)
}
function Find(x) {
if (x!= parents[x] ) {
parents[x] = Find(parents[x])
}
return parents[x]
}
function Union(x, y) {
px, py = Find(x), Find(y)
if (ranks[px] > ranks[py]) parents[py] = px
if (ranks[py] > ranks[px]) parents[px] = py
//