UF1和UF2的比较
来源:6-2 Quick Find
Mosea
2021-07-30
在数据量为10000的时候,UF1的时间是UF2的时间的接近4倍,但是数据量为10000的时候,UF2的时间反而增加了,请问bobo老师这个原因是为什么呢?
// 查找过程, 查找元素p所对应的集合编号
int find(int p){
assert( p>=0 && p<=count );
return id[p];
}
// 查看元素p和元素q是否所属一个集合
// O(1)复杂度
bool isConnected(int p,int q){
return find(p) == find(q);
}
// 合并元素p和元素q所属的集合
// O(n) 复杂度
void unionSet(int p,int q){
int pId = find(p);
int qId = find(q);
if(pId == qId)
return;
// 合并过程需要遍历一遍所有元素, 将两个元素的所属集合编号合并,就是合并两个集合
for(int i=0;i<count;i++){
if(id[i]==pId)
id[i]=qId;
}
}
int find(int p){
assert(p>=0&&p<=count);
while(p!=parent[p])
p = parent[p];
return p;
}
bool isConnected(int p,int q){
return find(p) == find(q);
}
void unionSet(int p,int q){
int pRoot = find(p);
int qRoot = find(q);
if(pRoot == qRoot)
return;
parent[pRoot] = qRoot;
}
备注:这里我将UF1和UF2的类放在同一个头文件UnionFind中,用不同的命名空间分开,没有像你给的代码一样两个放在不同头文件,后来我尝试将其放在两个头文件,其运行结果和放在一个文件的差不多,应该不是这个原因。
写回答
1回答
-
我在我的计算机上得不到 UF2 比 UF1 慢的结论,但是数据量大到一定程度,确实会出现 UF2 的优势变低的情况。我怀疑是因为当数据量达到一定程度,链式存储不断寻址,读取的数据的地址空间跳来跳去,导致的时间消耗增大,而 UF1 O(n) 复杂度的操作在同一地址顺次寻址,时间消耗更低。这不是算法的差异了,而是 CPU 底层优化的差异。
感兴趣可以在学习路径压缩以后再比较一下大数据量下,带路径压缩的 UF 和 UF1 的性能关系,应该有改善。
继续加油!:)
052021-08-02
相似问题