【发布时间】:2021-08-19 22:27:33
【问题描述】:
我已经为具有秩启发式和路径压缩的不相交集制作了一个模板。
template <typename T>
class disJSet
{
map<T,T> parent;
map<T,int> rank;
public:
//Linear time complexity
void makeSet(vector<T> it)
{
for(T i:it)
{
parent[i]=i;
rank[i]=0;
}
}
//Time complexity of O(log*n)
T find(T el)
{
if(el!=parent[el])
parent[el]=find(parent[el]);
return parent[el];
}
//Time complexity of O(log*n)
bool unionOp(T a,T b)
{
T a_id=find(a);
T b_id=find(b);
if(a_id==b_id)
return false;
if(rank[a_id]<rank[b_id])
parent[a_id]=b_id;
else
{
parent[b_id]=a_id;
if(rank[a_id]==rank[b_id])
{
rank[b_id]=rank[b_id]+1;
}
}
return true;
}
};
路径压缩在find() 方法中实现。为什么我们在路径压缩后不更新排名?
我的理由:每当有 find 调用时,每个中间节点都会因为路径压缩而成为叶子节点。并假设如果那是父级最长的子树,那么它的高度现在已经改变。但我们不会更新父/根节点的排名。
这可能会在联合操作中产生差异。例如,两个元素的联合将导致通过比较它们的等级来使一棵树成为另一棵树的孩子。但由于调用find(),排名可能无法代表树的最大高度。
【问题讨论】:
标签: c++ algorithm time-complexity disjoint-sets