您的位置:首页 > 编程语言

并查集入门与代码模板

2018-03-25 19:55 225 查看

并查集:

并查集算法在天梯赛和pat甲级里属于必须掌握的算法之一。

原理及适用范围:

给定一组数据及他们之间的关系,问任意两个元素是否在一个集合内。(例如,给定一个家谱,问某两个人是否是亲戚)很容易想到的是暴力搜索,但随着数据量的增加这种查找显然会超时。而并查集的原理则是在每一个集合中确定一个代表元,判断两个元素是否是一个集合只需要查看对应的代表元是否在相同。这将只需要O(1)时间即可完成查询。并查集其实是森林。
并不关心一个集合内的两个元素具体是怎样的联系

并查集的代码实现:

一般来说并查集需要三个操作,初始化,查询,合并。数据结构可采用多个数组或结构体。本文采用数组讲解。


初始化:

parent[]数组:parent[i]=a;    表示i的父亲是a。初始化所有的数据自己是自己的父亲。[cpp]
12e9b
view plain copy for(int i=1;i<=n;i++)  
    parent[i]=i;  
合并:
将两个元素放在一个集合(一棵树上)
void unio(int a,int b)
{
int ra=find(a);//查询a元素所在集合的代表元(即它的祖先)。
int rb=find(b);
if(ra!=rb)
parent[rb]=ra;//两个元素如果代表元不同,则把其中一个作为另一个的代表元。由此形成一棵树的形式。
}
查询:如何判断两个元素是否属于一个集合呢。该函数返回他们的代表元。
[cpp] view plain copy int find(int x)  
{  
    int root=x;  
    while(parent[root]!=root)  
        root=parent[root];  
    while(parent[x]!=root){  
        int t=parent[x];  
        parent[x]=root;  
        x=t;  
    }//循环的目的是路径压缩,是O(1)完成查询的关键,为了防止树的退化。把该元素及它所有的祖先的 父亲 全部设置为代表元.  
    return root;  
}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: