并查集

来源:互联网 发布:有关网络得现代诗歌 编辑:程序博客网 时间:2024/06/08 03:23

在一些有N个元素构成的一些单元素的集合,需要反复查找一个元素在哪一个集合中,判断两个数是否属于同一个集合,以及合并两个集合。并查集是一种树型的数据结构。用于处理不相交的集合( disjoint sets)的合并以及查询问题。在使用时用森林表示。

如集合A={0,1,3,6} , B={ 2,4 7} , C={5,8,9}其A,B,C分别构成三棵树,A,B,C共同构成一个森林,并查集一般用数组存储,如数组father。father[i]表示i的父节点,当father[x]==x时,表示x是根结点。在查找元素属于哪一个集合时,采用路径压缩的办法,可以避免树退化为线性,以保证查找的效率。它使用的O(n)的空间,单次查找时间为O(a(n)),一般可认为是常数:

以下是A,B,C集合在father数组的存储:

00102230425560728595

#include<iostream>using namespace std;#define n 11int father[n] = {0,0,2,0,2,5,0,2,5,5,9};int getRoot(int x);int Union(int x, int y);int main(){/*测试*/int i,j;cin >> i;i = getRoot(i);cout << i << endl;Union(1, 10);cin >> i;i = getRoot(i);cout << i << endl;return 0;}int getRoot(int x){int j = x,i;while (father[x] != x)         /*向上寻找根结点*/x=father[x]; while (father[j] != x){      /*状态压缩*/i = father[j];          /*记住j的父节点i*/father[j] = x;          /*将j直接连到根结点*/j = i;                  /*更新j为j原来的父节点*/}return x;                 // 返回根结点}int Union(int x, int y){x = getRoot(x);y = getRoot(y);  if (x != y) father[x] = y;return y;          //返回最后合并的根结点}
以上查找还可以使用递归的写法,这样getRoot函数如下:

int getRoot(int x){if (father[x] != x)father[x] = getRoot(father[x]);     //状态压缩,将沿途结点都连接到根结点后return father[x];                      // 返回根结点}



以下实现集合的查找以及集合的并:

0 0
原创粉丝点击