并查集的“并优化”(leader合并)和“查优化”(路径压缩)
来源:互联网 发布:sql 多个查询结果合并 编辑:程序博客网 时间:2024/06/08 18:35
在博文http://blog.csdn.net/stpeace/article/details/46506861中, 我们已经详细地了解了并查集, 不过, 那个程序略显粗糙, 下面我们考虑来优化一下。
先给出没有优化的代码吧:
// taoge的并查集#include <iostream>using namespace std;#define N 1000int leader[N + 1] = {0}; // 先搞一个充分大的数组// 初始化void setLeader(){int i = 1;for(i = 1; i <= N; i++){leader[i] = i; // 初始化时, 将自己初始化为自己的领导}}// 查找领导, 看看究竟是谁(实际上, 还可以进行路径压缩优化)int findLeader(int n) {int r = n;while(leader[r] != r){r = leader[r]; // 没找到的话, 一直往上找}return r;}// 将两个领导带领的团队融合, 从此, leaderX和leaderY建立了新的统一战线, 是一个大家庭团队了void uniteSet(int leaderX, int leaderY){leader[leaderX] = leaderY; // leader[leaderY] = leaderX;}// 输入数组, 每一行表示一个集合关系, 比如第一行表示3和4属于一个集合团队int input[] = {3, 4,4, 2,7, 6, 5, 1,3, 9,11, 8,6, 10,9, 13,11, 12,};// 测试数组, 测试每行的两个整数是否属于同一个大的家庭团队int test[] ={3, 2,9, 4,7, 10,6, 7,13, 4,8, 12,6, 9,4, 7,11, 10,1, 2,12, 13,7, 13,};int main(){int numberOfSets = 13; // 总共有13个元素, 即1, 2, 3, 4, ...., 13// 初始化领导setLeader();int i = 0;int j = 0;int n = sizeof(input) / sizeof(input[0]) / 2;for(j = 0; j < n; j++){int u = input[i++];int v = input[i++];// 找领导u = findLeader(u);v = findLeader(v);// 领导不相等, 则融合着两个团队, 合二为一if(u != v){uniteSet(u, v);numberOfSets--;}}i = 0;n = sizeof(test) / sizeof(test[0]) / 2;for(j = 0; j < n; j++){int u = test[i++];int v = test[i++];// 找领导u = findLeader(u);v = findLeader(v);// 如果领导不相同, 则不属于一个团队; 如果两个领导相同, 则肯定属于一个团队if(u != v){cout << "NO" << endl;}else{cout << "YES" << endl;}}// 其实, 经合并后, 最后的集合是4个:// {3, 4, 2, 9, 13}, {7, 6, 10,}, {5, 1}, {11, 8, 12}cout << numberOfSets << endl;return 0;}结果为:
YES
YES
YES
YES
YES
YES
NO
NO
NO
NO
NO
NO
4
实际上, 在findLeader的时候, 我们可以进行路径压缩, 这是“查优化”的关键点。而在并的过程中, 也可以进行“并优化”, 不过, “并优化”的作用不太明显, 如下:
// taoge的并查集#include <iostream>using namespace std;#define N 1000int leader[N + 1] = {0}; // 先搞一个充分大的数组// 初始化void setLeader(){int i = 1;for(i = 1; i <= N; i++){leader[i] = i; // 初始化时, 将自己初始化为自己的领导}}// 查找领导, 看看究竟是谁int findLeader(int n) {int r = n;while(leader[r] != r){r = leader[r]; // 没找到的话, 一直往上找}// "查优化"的本质是路径压缩, 最终使得所有员工的直接上司均为该组的leaderint i = n;int j = 0;while(i != r){j = leader[i];leader[i] = r;i = j;}return r;}// 将两个领导带领的团队融合, 从此, leaderX和leaderY建立了新的统一战线, 是一个大家庭团队了void uniteSet(int leaderX, int leaderY){// 我个人认为:"并优化"的作用不是很大if(leaderX < leaderY){leader[leaderX] = leaderY;}else{leader[leaderY] = leaderX;}}// 输入数组, 每一行表示一个集合关系, 比如第一行表示3和4属于一个集合团队int input[] = {3, 4,4, 2,7, 6, 5, 1,3, 9,11, 8,6, 10,9, 13,11, 12,};// 测试数组, 测试每行的两个整数是否属于同一个大的家庭团队int test[] ={3, 2,9, 4,7, 10,6, 7,13, 4,8, 12,6, 9,4, 7,11, 10,1, 2,12, 13,7, 13,};int main(){int numberOfSets = 13; // 总共有13个元素, 即1, 2, 3, 4, ...., 13// 初始化领导setLeader();int i = 0;int j = 0;int n = sizeof(input) / sizeof(input[0]) / 2;for(j = 0; j < n; j++){int u = input[i++];int v = input[i++];// 找领导u = findLeader(u);v = findLeader(v);// 领导不相等, 则融合着两个团队, 合二为一if(u != v){uniteSet(u, v);numberOfSets--;}}i = 0;n = sizeof(test) / sizeof(test[0]) / 2;for(j = 0; j < n; j++){int u = test[i++];int v = test[i++];// 找领导u = findLeader(u);v = findLeader(v);// 如果领导不相同, 则不属于一个团队; 如果两个领导相同, 则肯定属于一个团队if(u != v){cout << "NO" << endl;}else{cout << "YES" << endl;}}// 其实, 经合并后, 最后的集合是4个:// {3, 4, 2, 9, 13}, {7, 6, 10,}, {5, 1}, {11, 8, 12}cout << numberOfSets << endl;return 0;}结果同样是:
YES
YES
YES
YES
YES
YES
NO
NO
NO
NO
NO
NO
4
如果还有理解不清楚的, 请参考我之前的博文http://blog.csdn.net/stpeace/article/details/46506861
1 0
- 并查集的“并优化”(leader合并)和“查优化”(路径压缩)
- 并查集的优化---路径压缩与启发式合并
- 并查集的优化:按秩合并和路径压缩
- 并查集(两个优化—按秩合并、路径压缩) poj2492
- 并查集优化之路径压缩
- 并查集的两个优化(秩优化+路径压缩)
- 并查集的两种优化(按秩合并,路径压缩)
- 并查集的启发式合并 和 路径压缩
- 并查集(按秩合并、路径压缩)
- 并查集(路径压缩 && 启发式合并!!!)
- HDU 1856 More is better(并查集路径压缩+剪枝优化+暴力枚举)
- 数据结构实现之并查集(使用按秩合并和路径压缩)
- 十、森林与并查集---(6)并查集路径压缩优化
- Disjointset 并查集(按秩合并,与路径压缩)的模板
- 亲戚 (并查集路径压缩)
- 并查集 路径压缩(详解)
- 并查集(路径压缩)
- 并查集的优化
- c,c++,java用户自定义标识符命名规则比较
- malloc原理和内存碎片
- 数据结构之线索二叉树
- 27.指针函数的调用
- linux 在proc文件系统下创建文件
- 并查集的“并优化”(leader合并)和“查优化”(路径压缩)
- 导出成excel文件
- JSP页面中四种“返回按钮”的使用
- 指针和结构体
- 【华为oj】整型数组合并
- #15 3Sum
- 生成关键字是1~N的随机二叉查找树的函数
- 【机房收费个人版】触发器与存储过程
- TaintDroid: An Information-Flow Tracking System for Realtime Privacy Monitoring on Smartphones