数据结构 并查集 路径压缩
来源:互联网 发布:水利网络培训 编辑:程序博客网 时间:2024/06/06 07:01
经常会遇到对于给定的n个点,求出他们能否相互连通的问题,常规的做法可能是用二维数组进行标记处理,但是这样的空间使用是O(n^2),当数据量很大的时候,这个消耗是很恐怖的,所以这里我们引入并查集的这种数据结构。
树是一种数据结构,它的特点在于所有的点有且仅有一个根节点,如果我们能构造一棵树,并把所有的树按照相互关系装入这棵树,那么他们就是属于一个集合,他们都互相连通的。
我们可以用数组来构建这样一个模型。
int parent[N];
用这样一个数组,记录每个点属于哪个集合,最初所有的点都是孤立的。所以等于它本身。
每次我们都需要查询他们所属的集合,是否为同一个集合,如果不是,就可以把它们连通。
而且我们可以建立简单的树形关系:
这样查询的次数为层数。
注意有一种最坏的情况,就是如同链表那样,查询次数就接近总数的一半了。
int findx(int x){ int r=x; while(parent[r] !=r) r=parent[r]; return r;}
这里我们给出一个很简单的查询方法,首先用变量r存储需要查询的值,然后每次查询r的父节点,保存它的父节点,查询它父节点的父节点……最后就能找到答案。
但我们想想,对于每个数,我们每次都需要去查询它根节点的时候都要很多时间,而且我们真实需要的并不是它的父节点的值,而是它根节点的值。
如果我们能构建如下的树:
这样查询的效率就是O(1),因为只有一层,所以我们查询的时间很少,这里就用到了路径压缩,我们先看压缩过的代码:
int findx(int x) { if (x != parent[x]) { parent[x] = find(parent[x]); } return parent[x];}
这样我们每次都会去更新父节点的值变成根节点的值。
但是用递归会出现一种问题,爆堆栈。
windows对堆栈的限制很大,所以我们可以放弃递归,用递推式。
int findx(int x){ int k, j, r; r = x; while(r != parent[r]) r = parent[r]; k = x; while(k != r) { j = parent[k]; parent[k] = r; k = j; } return r; }
这种非递归方式更安全。
1 0
- 数据结构 并查集 路径压缩
- poj 1182 食物链(数据结构:并查集+路径压缩)
- 并查集 & 路径压缩
- 【并查集+压缩路径】
- 并查集路径压缩
- 并查集路径压缩
- 并查集路径压缩
- 并查集路径压缩
- 并查集压缩路径
- 并查集 压缩路径
- 并查集路径压缩
- 并查集 ---压缩路径
- 并查集 路径压缩
- 并查集压缩路径
- 并查集压缩路径
- 并查集-路径压缩
- 并查集 路径压缩
- 并查集&&压缩路径
- 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第55讲:PHP smarty模板自定义函数
- UVA 11809 Floating-Point Numbers
- linux中查看现在使用的shell是ksh还是bash?以及怎样修改?
- 如何验证C语言中小数默认是double类型
- 关于java.lang.VerifyError的另外一种错误原因
- 数据结构 并查集 路径压缩
- Python文件操作注意事项
- OpenGLES下进行渲染
- MySQL无法存储Emoji表情问题
- javascript面向对象编程
- Hello world
- gdb 调试
- android imageview
- nyoj 8一种排序