Quick Union
来源:互联网 发布:arduino json 编辑:程序博客网 时间:2024/06/11 02:42
-----------------siwuxie095
Quick Union
这里介绍并查集的另外一种实现思路:Quick Union
这种实现思路通常是并查集的常规实现思路,而且它的时间效率非常高
具体表示:将每一个元素,都看做是一个节点
不过这个节点和树中的节点稍有不同,树中节点的指针是指向自己的孩子,
而并查集中节点的指针却是指向自己的父亲
所以在并查集中,就有可能存在这样的一种情况:元素3 有一个指针指向
元素 2,即 2是父节点,3 是子节点,这就代表了 2 和 3 互相连接
另外,对于元素 2来说,如果它本身已经是根了的话,它的指针只要指向
自己就好了,如下:
在上面的基础上,如果有元素 1想和 2 或 3 连接,就应该将 1 指向父亲
的指针指向 2和 3 组成的这棵树的根节点,也就是 2,如下:
在上面的基础上,再加另外一个集合 5、6、7
如果想让元素 5和元素 2 连接在一起,只需要让 5 相应的指针指向 2即可
另外,如果不是想让元素 5和元素 2 连接在一起,而是想让元素 7 和
元素 3连接在一起,那么最终所形成的树,依然是上图所示的样子
这是因为 7所在的树的根是 5,3所在的树的根是 2,所以依然是将 5
和 2连接在一起,即让 5 的指针指向 2
具体在数据表示上,虽然之前使用的一直是指针这个词,但由于每个
元素只要单独存储一个变量,即父亲具体是哪个元素即可
所以在这里,依然使用数组来表示
称这个数组为parent,parent[i] 就表示元素 i 所指向的父亲元素
初始化时,parent[i] = i,即 每个元素的父亲元素都指向自己
程序:Quick Union 的实现
UnionFind.h:
#ifndef UNIONFIND_H
#define UNIONFIND_H
#include <cassert>
using namespace std;
//并查集:Quick Union
namespace UF
{
class UnionFind
{
private:
int *parent;
int count;
public:
UnionFind(int count)
{
parent =newint[count];
this->count = count;
//在初始情况下,并查集里的元素,两两之间互不连接
for (int i =0; i < count; i++)
{
parent[i] = i;
}
}
~UnionFind()
{
delete []parent;
}
int find(int p)
{
assert(p >=0 && p < count);
//不断通过p来追溯它的父亲,直到p等于自己的父亲,
//即 p 节点已经成为了根节点,直接 return即可
//(即返回的是p所在集合的根节点)
while (p != parent[p])
{
p = parent[p];
}
return p;
}
//看p、q二者是否对应同样的根,来判断它们是否连在一起
//(p、q的根节点如果相同,则相连)
bool isConnected(int p,int q)
{
return find(p) == find(q);
}
void unionElements(int p,int q)
{
int pRoot = find(p);
int qRoot = find(q);
if (pRoot == qRoot)
{
return;
}
//互换亦可
parent[pRoot] = qRoot;
}
};
}
#endif
UnionFindTestHelper.h:
#ifndef UNIONFINDTESTHELPER_H
#define UNIONFINDTESTHELPER_H
#include"UnionFind.h"
#include <iostream>
#include <ctime>
using namespace std;
namespace UnionFindTestHelper
{
void testUF(int n)
{
//设置随机种子
srand(time(NULL));
UF::UnionFind uf = UF::UnionFind(n);
time_t startTime = clock();
//先进行n次的并,即 Union 操作
for (int i =0; i < n; i++)
{
int a = rand() % n;
int b = rand() % n;
uf.unionElements(a, b);
}
//再进行n次的查,即 Find 操作
for (int i =0; i < n; i++)
{
int a = rand() % n;
int b = rand() % n;
uf.isConnected(a, b);
}
time_t endTime = clock();
//打印2*n个操作耗费的时间
cout <<"UF, " << 2 * n << " ops, " <<double(endTime - startTime) / CLOCKS_PER_SEC
<<" s" << endl;
}
}
#endif
main.cpp:
#include"UnionFindTestHelper.h"
#include <iostream>
using namespace std;
int main()
{
//规模是十万
int n =100000;
UnionFindTestHelper::testUF(n);
system("pause");
return0;
}
运行一览:
【made by siwuxie095】
- quick-union
- Quick-Union
- Quick Union
- 【算法】quick union
- Quick-Union[Algorithm]
- Week1-3Quick Union
- quick-union【连通图】
- 算法 加权quick-union
- 加权quick-union算法
- 3.weighted quick union
- 2.quick find and quick union
- 1.3:Union-Find算法-----quick-union算法
- union-find中(quick-union)算法
- union-find下(加权quick-union)算法
- Weighted version of quick union
- quick-union-weighted【连通图】
- 1.3:Union-Find算法-----quick-union算法的改进(加权的quick-union算法)
- 算法代码实现之Union-Find,Java实现,quick-find、quick-union、加权quick-union(附带路径压缩优化)
- LINK2019错误分析
- 在子线程中初始化地图会出现的警告以及解决方法
- ProFTPD限速办法
- 苹果公司向中国征收30%"苹果税"
- 继承AppCompatActivity的Activity无法隐藏标题栏及继承Activity在Studio中直接隐藏标题
- Quick Union
- 再谈神经网络反向传播原理
- http://www.cnblogs.com/ylbtech/p/6292424.html
- select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET
- mybatis foreach 出错
- 洛谷P1850 换教室noip提高day1题
- [Amazon Alexa开发]为自己的App申请Login with Amazon的key
- 哈希表的操作
- Http、Https 和 Socket 的区别与联系