“树”据结构:并查集从入门到AC

“树”据结构:并查集

前言

在一组数据中,数据被分为了不同的集合,那么其中的集合往往可以用树形来表示。而区分集合,与查找集合的元素,就会成为核心的问题。并查集主要就是解决这类问题,因此并查集算法的核心也就是查找与区分。
并查集通过一个一维数组来实现,因此,给我们提供了更大的时间和空间上的便利。通过一维数组来维护一个森林,也就是维护由不同树为子集构成的集合。
问题示例:
有10个学生,1号与2号同班,3号和5号同班,4号和6号同班,7号和3号同班,8号和10号同班,9号和2号同班,8号和4号同班。
然后一般是要求解不同的班级数or输入序号查询同班同学
这类问题都是经典的并查集模板。

算法设计

先动动笔算下我们需要的结果:
1,2,9一个班级
3,5,7一个班级
4,6,8,10一个班级
首先先将一个一维数组初始化,设数组的值为其班级序号,假设每个学生都来自不同的班级,即f[i]=i。
由此f[1]=1,f[2]=2,f[3]=3,…f[10]=10。
然后我们再把结点合并成树,树内部再做处理。
由结点合并为树:以靠左优先进行同班合并,由于输入的条目是1 2,所以2号的2班消失合并到1班
在这里插入图片描述
接下来我们要准备的函数是,搜索同班同学的归属,我们先写一个深度搜索:

int dfs(int v)
{
   
    if(a[v]==v)
        return v;
    else
    {
   
        dfs(a[v]);
    }
}

于是我们可以搜索到同班同学的最终归属。
而当我们读到输入条目:9号与2号同班的时候,由于2号班级已经消失成为了1号班级(形成了树,而不是单一结点),这时候我们将整个结点归到9号之下:
在这里插入图片描述
但这时候我们的算法没有完成,因为在最后的数组下标里,1、2、9明明同属于9班2号学生却属于1班,2向1的指针就多余了,那么我们需要略微处理下搜索算法来处优化冗余数据,也称路径压缩:
在这里插入图片描述
如此处理,当最终搜索完成的时候,只要每次存在f[i]=i&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值