并查集基础浅谈

  • 并查集是什么,有什么用?

数据结构中,有一种数据结构叫:树;首先,我们先创建一棵树

上面是一颗已经创建好的数,如果用数组来表示,就是

​
​
int pre[7]={0,1,1,1,2,2,3,3};

​

​

数组下标i表示第几个节点,数字值表示其父亲节点,也就是前驱(pre[0]我们不要,就设置成0)。

假设现在,我们要查询第七个节点的最小根节点是谁(图来说就是枢纽),很明显,是1;所以并查集的一个功能就是查找根。

  • 查找功能:
int find(int x){
	int r=x;
	while(pre[r]!=r){
		r=pre[r];
	}
  int i=x , j ;
    while( i != r ) //路径压缩
    {
        j = pre[ i ]; // 在改变上级之前用临时变量  j 记录下他的值 
        pre[ i ]= r ; //把上级改为根节点
        i=j;
	}
    return r ;
}

上面用到压缩路径,就是一种减少查找时间的一种优化。比如当数据比较庞大时,你要查找叶子节点,然后一个一个往上找,必然需要时间很多。压缩路径就是第一次,我花了很多时间,但是第二次查找时,其及父亲节点都能比较快速找到最初的根节点。原理是将每一个查找时遇到的点都赋值为根节点的下标,从而减少查找时间。

下面我们来看个例子

#include<iostream>
using namespace std;
//并查集
int pre[8]={0,1,1,1,2,2,3,3};
int find(int x){
	int r=x;
	while(pre[r]!=r){
		r=pre[r];
	}
  int i=x , j ;
    while( i != r ) //路径压缩
    {
        j = pre[ i ]; // 在改变上级之前用临时变量  j 记录下他的值 
        pre[ i ]= r ; //把上级改为根节点
        i=j;
	}
    return r ;
}		
/*int join(int x,int y){	
} */
int main(){
		find(6);
		for(int i=1;i<=7;i++)\
			cout<<pre[i]<<" ";
	
}

结果

合并

先看代码

int join(int x,int y){	
	int tx=find(x);
	int ty=find(y);
	if(tx!=ty)
		pre[x]=y;//将y作为x的根节点 
} 

这是将两节点合并,比较简单。

以上就是并查集的一些最基础内容。可以解决一些多路连通等问题比较方便!

猜你喜欢

转载自blog.csdn.net/sjs_caomei/article/details/81196829
今日推荐