并查集
最基础的并查集,使用数组完成,数组下标为节点的数值,数组中的数值表示节点的父亲
最基础的并查集代码如下:
1 #include<iostream> 2 using namespace std; 3 int f[10010]; 4 void init() 5 { 6 for (int i = 0; i < 10; i++) f[i] = i;//一开始每个节点孤立,自己是自己的父亲 7 } 8 int find(int x) 9 { 10 if (f[x] == x) return x; 11 else return find(f[x]);//寻找父亲直到找到根节点 12 } 13 void merge(int i, int j) 14 { 15 f[find(i)] = find(j); 16 }
路径压缩后的并查集:
1 #include<iostream> 2 using namespace std; 3 int f[10010]; 4 void init() 5 { 6 for (int i = 0; i < 10; i++) f[i] = i;//一开始每个节点孤立,自己是自己的父亲 7 } 8 int find(int x) 9 { 10 if (f[x] == x) return x; 11 else 12 { 13 f[x] = find(f[x]);//路径压缩,在查询过程中把每一个节点父亲设置为根节点 14 return f[x]; 15 }//寻找父亲直到找到根节点 16 } 17 void merge(int i, int j) 18 { 19 f[find(i)] = find(j); 20 }
终极并查集:按秩排序(简单的树成为复杂的树的子树,使树的深度尽可能小。
1 #include<iostream> 2 using namespace std; 3 int f[10010]; 4 int rankk[10010];//记录树的深度 5 void init() 6 { 7 for (int i = 0; i < 10; i++) 8 { 9 f[i] = i; 10 rankk[i] = 1; 11 }//一开始每个节点孤立,自己是自己的父亲 12 } 13 int find(int x) 14 { 15 if (f[x] == x) return x; 16 else 17 { 18 f[x] = find(f[x]);//路径压缩,在查询过程中把每一个节点父亲设置为根节点 19 return f[x]; 20 }//寻找父亲直到找到根节点 21 } 22 void merge(int i, int j) 23 { 24 int m = find(i); 25 int n = find(j); 26 if (rankk[m] <= rankk[n]) f[m] = n;//简单的树成为复杂的树的子树,尽可能使树的深度小 27 else f[n] = m; 28 if (rankk[m] == rankk[n] && m != n) rankk[n]++;//两棵同高不同根的树合并时,根节点深度加1 29 }