- 并查集是什么,有什么用?
数据结构中,有一种数据结构叫:树;首先,我们先创建一棵树
上面是一颗已经创建好的数,如果用数组来表示,就是
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的根节点
}
这是将两节点合并,比较简单。
以上就是并查集的一些最基础内容。可以解决一些多路连通等问题比较方便!