并查集的实现主要有两个功能:
1.find(x),返回x的根结点,可以将其想象为一颗树。
2.union(x,y),将x,y融合为一颗树.
具体实现有
1.parent[x]:指的是x的根结点.
2.rank[x]:指以x为根结点时,从叶子到根结点的最大距离(hops)。
为了使union方便,在进行union(x,y)操作时,选择将rank小的树的根结点改为rank较大树的根结点。
仅仅改变rank小的根结点的parent。
3.union的时候,大部分的rank不变,只有在融合两个具有相同的rank值时,被融合的rank那一方才会加1.
代码如下:
/************并查集**********/ class UnionFind { public: UnionFind(int len)//初始化 { length = len; rank.resize(len); parent.resize(len); for(int i = 0; i < length; i++) { rank[i] = 0; parent[i] = i; } } /********判断能否融合*****/ bool unite(int x, int y) { int a = find(x); int b = find(y); if(a == b) { return false; } else { if(rank[a] == rank[b]) { parent[a] = b; rank[b]++; //只有两棵树的rank相等时候,union的时候某一方的rank不变 } else if(rank[a] < rank[b]) { parent[a] = b; } else { parent[b] = a; } } return true; } int find(int x) //返回根结点 { if(parent[x] == x) //满足parent[x] == x 时候返回,找到根结点 { return x; } else { return find(parent[x]); } } public: vector<int> rank; //rank[x] = the max number of hops from a leaf to x vector<int> parent; //根结点 int length; };
并查集的优化还有path compression的优化方案。在此不在详述。