【并查集】概念的温习与用法的升华
作者:互联网
并查集适用场景:
快速的判断某个元素属于哪个集合,快速的合并两个集合。</p>
暴力的做法中,查询的复杂度为O(1),合并的复杂度则很高。
在并查集中,并查集的复杂度为接近O(1)。
并查集的特点:
以树的形式来维护一个集合。
根节点的编号就是当前集合的编号。
保存当前节点的父节点。
当查找一个元素所在的集合时:
1.去找当前节点的父节点。
2.如果当前节点不是根节点,那么就继续寻找其父节点。</p>
3.如果是树根,那么p[x] = x;</p>
并查集的路径压缩优化:
采用递归的思想
将当前节点直接连接到祖宗节点上
p[x] = find(p[x]);
非递归的思想
int find(int x)
{
int k, j, r;
r = x;
while(r != parent[r]) //查找跟节点
r = parent[r]; //找到跟节点,用r记录下
k = x;
while(k != r) //非递归路径压缩操作
{
j = parent[k]; //用j暂存parent[k]的父节点
parent[k] = r; //parent[x]指向跟节点
k = j; //k移到父节点
}
return r; //返回根节点的值
}
并查集的按秩合并优化:
高度矮的树合并到高度高的树上
void unite(int x,int y)
{
x=find(x);
y=find(y);
if(x==y) return ;
if(rank[x]<rank[y])
parent[x]=y; // 合并是从rank小的向rank大的连边
else
{
parent[y]=x;
if(rank[x]==rank[y]) rank[x]++;
}
}
参考文章:
【CSDN】并查集的优化:按秩合并和路径压缩
【知乎】ACM——可撤销并查集教程
标签:parent,int,查集,find,升华,集合,温习,节点 来源: https://www.cnblogs.com/bz-2021/p/16341425.html