【并查集】并查集实现原理以及应用
2017-08-16 12:44
288 查看
实现原理
一种树型数据结构,用于处理不相交集合(Disjoint Sets)的合并以及查询;一开始让所有元素独立成树,也就是只有根节点的树;然后根据需要将关联的元素(树)进行合并;合并的方式仅仅是将一棵树最原始的节点的父亲索引指向另一棵树;初始化
初始化father:各个节点独立成树,并且其father[i]=-1,
father[i]
0 1 2 3 4 5 6 7 8 9
-1 -1 -1 -1 -1-1-1-1 -1
每个集合里面存放的都是自己的父节点,一直找,直到一个节点的值为负数,表示该节点为这个集合的根节点。根节点的绝对值,表示该集合有多少个元素
FindIdx查找该节点的根
因为每个节点的值为这个节点的父节点,所以以节点的值为下标,一直向上查找,直到一个节点的值为负数,那么找到了根节点。即:该集合的代表。
合并Union
找到两个节点的根节点,将他们的值相加存放到根节点1,根节点2的值为节点1的下标。这样将两个集合合并成以根节点1的集合中。
代码实现
#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> #include<vector> using namespace std; // 0 1 2 3 4 5 6 // -1 -1 -1 -1 -1 -1 -1 class UnionFindSet { public: UnionFindSet(size_t size) { s.resize(size, -1); } size_t FindIdx(int x)//找该位置的根节点的下标 { int root = x; while (s[root] >= 0) root = s[root]; return root; } void Union(int x1, int x2)//合并两个 { int root1 = FindIdx(x1); int root2 = FindIdx(x2); if (root1 != root2) { s[root1] += s[root2]; s[root2] = root1; } } bool IsSameSet(int x1, int x2)//判断两个集合是否相等 { return FindIdx(x1) == FindIdx(x2); } size_t UnionSize()//求有几个集合 0 不是一个集合 { size_t count = 0; for (size_t i = 0; i < s.size(); ++i) { if (s[i] < 0) count++; } return count - 1; } void PrintSet() { for (size_t i = 0; i < s.size(); ++i) cout << i << " "; cout << endl; for (size_t i = 0; i < s.size(); ++i) { if (s[i] < 0) cout << s[i] << " "; else cout << s[i] << " "; } cout << endl; } private: vector<int> s; }; void Test() { UnionFindSet un(8); un.Union(1, 3); // -1 un.Union(3, 7); un.Union(2, 4); un.Union(4, 5); un.Union(5, 6); un.PrintSet(); cout<< un.UnionSize()<<endl; }
初始化
// 0 1 2 3 4 5 6 7 8
// -1 -1 -1 -1 -1 -1 -1 -1 -1
(1)un.Union(1, 3);
查找1的根节点为 本身,查找 3的根节点为本身,然后合并,
1的值 = -1 + -1 = -2。//改集合有两个元素。
3的值 = 1;//3的父节点为节点1
// 0 1 2 3 4 5 6 7 8
// -1 -2 -1 1 -1 -1 -1 -1 -1
(2)un.Union(3, 7);
3的根节点为1,而1是该集合的代表,
7集合的代表为本身;
合并,
1的值为 = -2 + -1 = -3;//该集合有三个元素
7的值为 = 1。//节点1
应用
优化——路径压缩思想
每次查找的时候,如果路径较长,则修改信息,以便下次查找的时候速度更快。
实现
第一步,找到根结点。
第二步,修改查找路径上的所有节点,将它们都指向根结点
图的最小生成树克鲁斯卡尔算法
图的最小生成树
相关文章推荐
- Android中免Root实现Hook的Dexposed框架实现原理解析以及如何实现应用的热修复
- LockSupport的源码实现原理以及应用
- Android中免Root实现Hook的Dexposed框架实现原理解析以及如何实现应用的热修复
- 解析php中session的实现原理以及大网站应用应注意的问题
- Android 中免 Root 实现 Hook 的 Dexposed 实现原理解析以及如何实现应用的热修复
- iOS开发 runtime实现原理以及实际开发中的应用
- iOS开发 runtime实现原理以及实际开发中的应用
- 18位身份证号验证算法的原理以及C#实现和在管理系统的应用
- 解析php中session的实现原理以及大网站应用应注意的问题
- Android中免Root实现Hook的Dexposed框架实现原理解析以及如何实现应用的热修复
- Android中免Root实现Hook的Dexposed框架实现原理解析以及如何实现应用的热修复
- iOS开发 runtime实现原理以及实际开发中的应用
- 06.枚举的作用,实现原理以及应用
- 【STL】栈的实现原理以及应用
- 关于卷积神经网络原理以及代码实现应用的几点思考
- Android中免Root实现Hook的Dexposed框架实现原理解析以及如何实现应用的热修复
- Android中免Root实现Hook的Dexposed框架实现原理解析以及如何实现应用的热修复
- Spring AOP 实现原理以及应用