Skip to content

Commit 108a12e

Browse files
committed
Compare the performance between recursive and non-recursive implementation of path compression in UF.
1 parent 09a8aa9 commit 108a12e

File tree

2 files changed

+92
-2
lines changed

2 files changed

+92
-2
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
//
2+
// Created by liuyubobobo on 6/16/17.
3+
//
4+
5+
#ifndef OPTIONAL_01_SAME_CASES_TEST_FOR_UF_UNIONFIND6_H
6+
#define OPTIONAL_01_SAME_CASES_TEST_FOR_UF_UNIONFIND6_H
7+
8+
#include <cassert>
9+
10+
using namespace std;
11+
12+
// 我们的第六版Union-Find, 路径压缩使用递归的方式
13+
namespace UF5{
14+
15+
class UnionFind{
16+
17+
private:
18+
// rank[i]表示以i为根的集合所表示的树的层数
19+
// 在后续的代码中, 我们并不会维护rank的语意, 也就是rank的值在路径压缩的过程中, 有可能不在是树的层数值
20+
// 这也是我们的rank不叫height或者depth的原因, 他只是作为比较的一个标准
21+
// 关于这个问题,可以参考问答区:http://coding.imooc.com/learn/questiondetail/7287.html
22+
int* rank;
23+
int* parent; // parent[i]表示第i个元素所指向的父节点
24+
int count; // 数据个数
25+
26+
public:
27+
// 构造函数
28+
UnionFind(int count){
29+
parent = new int[count];
30+
rank = new int[count];
31+
this->count = count;
32+
for( int i = 0 ; i < count ; i ++ ){
33+
parent[i] = i;
34+
rank[i] = 1;
35+
}
36+
}
37+
38+
// 析构函数
39+
~UnionFind(){
40+
delete[] parent;
41+
delete[] rank;
42+
}
43+
44+
// 查找过程, 查找元素p所对应的集合编号
45+
// O(h)复杂度, h为树的高度
46+
int find(int p){
47+
assert( p >= 0 && p < count );
48+
49+
// path compression 2, 递归算法
50+
if( p != parent[p] )
51+
parent[p] = find( parent[p] );
52+
return parent[p];
53+
}
54+
55+
// 查看元素p和元素q是否所属一个集合
56+
// O(h)复杂度, h为树的高度
57+
bool isConnected( int p , int q ){
58+
return find(p) == find(q);
59+
}
60+
61+
// 合并元素p和元素q所属的集合
62+
// O(h)复杂度, h为树的高度
63+
void unionElements(int p, int q){
64+
65+
int pRoot = find(p);
66+
int qRoot = find(q);
67+
68+
if( pRoot == qRoot )
69+
return;
70+
71+
// 根据两个元素所在树的元素个数不同判断合并方向
72+
// 将元素个数少的集合合并到元素个数多的集合上
73+
if( rank[pRoot] < rank[qRoot] ){
74+
parent[pRoot] = qRoot;
75+
}
76+
else if( rank[qRoot] < rank[pRoot]){
77+
parent[qRoot] = pRoot;
78+
}
79+
else{ // rank[pRoot] == rank[qRoot]
80+
parent[pRoot] = qRoot;
81+
rank[qRoot] += 1; // 此时, 我维护rank的值
82+
}
83+
}
84+
};
85+
}
86+
87+
#endif //OPTIONAL_01_SAME_CASES_TEST_FOR_UF_UNIONFIND6_H

06-Union-Find/Course Code (C++)/Optional-01-Same-Cases-Test-for-UF/main.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ using namespace std;
88
// 在这里, 我们对于不同的UnionFind的实现, 使用相同的测试用例, 让测试结果更加准确
99
int main() {
1010

11-
// 使用1000000的数据规模
12-
int n = 1000000;
11+
// 使用5,000,000的数据规模
12+
int n = 5000000;
1313

1414
srand( time(NULL) );
1515

@@ -47,5 +47,8 @@ int main() {
4747
UF5::UnionFind uf5 = UF5::UnionFind(n);
4848
UnionFindTestHelper::testUF("UF5", uf5, unionTest, connectTest);
4949

50+
UF5::UnionFind uf6 = UF5::UnionFind(n);
51+
UnionFindTestHelper::testUF("UF6", uf6, unionTest, connectTest);
52+
5053
return 0;
5154
}

0 commit comments

Comments
 (0)