并查集

我之前在无向图的连通性问题上使用到了并查集的方法。现在我系统整理一下。

并查集:

是什么:

它是一种用来管理元素分组情况的一个数据结构。


做什么:
  • 查询元素a和元素b是否在同一组。
  • 合并元素a和元素b所在的组。
    注意:并查集虽然可以进行合并操作,但是无法进行分割操作。

结构:

并查集是使用树形结构实现的,但是不是二叉树。
每个元素对应一个结点,每个组对应一棵树。


实现过程
  1. 初始化:
    用一个数组保存每个结点的父结点,最开始,每个结点的父结点都是自己,它们互相独立。没有边

     void Init()
     {
     	for(int i=0; i<n; i++)
     	{
     		par[i] = i;	
     	}	
     	return 0;
     }
    
  2. 合并:
    从一个组的根向另一个组的根连边,这样两棵树就变成一棵树,即将两个集合合并为一个集合。

     /*合并x和y所属的集合*/
     void unite(int x, int y)
     {
     	if(find(x)==find(y)) return;
     	else{
     		par[find(y)] = find(x);
     	}
     }	
    
  3. 查询:
    查询两个结点是否为同一个组:只要找到这两个结点的父结点是不是一个“人”,就能够知道是否为同一个组了。

     /*查找根节点*/
     int find(int x)
     {
         int r = x;
         while(r!=pre[r])
         r = pre[r];
         return r;
     }
    
路径压缩:

如果一个树是长长的一棵,那么从叶子开始找它的根结点,那么复杂度就显得十分高了。所以我们要采用一个技巧——路径压缩,就是一旦找到每一个结点的根结点,直接把这个结点和它变成**“直属”**关系,即直接连到根上,这样下次再次查询就不会自顶向上一个个找了。

int find(int x)
{
    int r = x;
    while(r!=pre[r])
    r = pre[r];

    int i = x;//路径压缩 
    int j;  
    while(i != r)
    {
        j = pre[i];
        pre[i] = r;
        i = j;
    }
    return r;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值