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回答

liuyubobobo

2021-07-30

我在我的计算机上得不到 UF2 比 UF1 慢的结论,但是数据量大到一定程度,确实会出现 UF2 的优势变低的情况。我怀疑是因为当数据量达到一定程度,链式存储不断寻址,读取的数据的地址空间跳来跳去,导致的时间消耗增大,而 UF1 O(n) 复杂度的操作在同一地址顺次寻址,时间消耗更低。这不是算法的差异了,而是 CPU 底层优化的差异。


类似我的这篇文章介绍的机制:https://mp.weixin.qq.com/s?__biz=MzU4NTIxODYwMQ==&mid=2247486056&idx=1&sn=bf60187c7c2de2dcc863be33b4a28341&chksm=fd8ca52ecafb2c384524a4b470693ab5f522e323debc9afaf4a2ba27651d5aba1f7d015bd6cd&token=1288480109&lang=zh_CN#rd


感兴趣可以在学习路径压缩以后再比较一下大数据量下,带路径压缩的 UF 和 UF1 的性能关系,应该有改善。


继续加油!:)

0
5
Mosea
非常感谢!
2021-08-02
共5条回复

算法与数据结构(C++版) 面试/评级的算法复习技能包

课程专为:短时间内应对面试、升职测评等艰巨任务打造

11187 学习 · 1614 问题

查看课程