并查集的两种优化(按秩合并,路径压缩)

并查集是建立在对不相交集合进行的两种基本操作的基础之上的。操作之一:检索某元素属于哪个集合;操作之二:合并两个集合。黑书上说了,这种结构显然可以用链表或森林实现,显然用链表进行查询时间复杂度应该是O(n)级别的,而使用森林进行查访如果处理的好时间复杂度就应该是O(logn)。对于用森林来实现并查集,黑书上有句加点话我同样认为很重要“用树根来标识一个集合”。于是对于并查集就存在这么两个很关键的优化操作:第一,让深度小的数成为深度较大的树的子树,这个优化成为启发式合并,这样做之后树的深度为O(logn);第二,找到u所在的树根v以后,把从u到v的路径上所有点的父亲都设置为v,这个优化称作路径压缩。既然第一个优化叫做启发式合并,那么很重要的就是启发式函数的选取,一般可以用树的深度作为启发函数值,但由于路径压缩优化,树的深度是在不断变化的。这时候便可引入一个秩,按我的理解就是一颗树收取与其等秩的树的次数,因为合并的最底层操作就是两个独立元素的合并,所以rank越大,树中的元素越多,显然rank的初值都是0。

1) 按秩合并:

按秩合并的基本思想是使包含较少结点的树德根指向包含较多结点的树的根,而这个树的大小可以抽象为树的高度,即高度小的树合并到高度大的树,这样资源利用更加合理。
     为了实现一个按秩合并的不想交集合森林,要记录下秩的变化。对于每个结点x,有一个整数rank[x],它是x的高度(从x到其某一个后代叶结点的最长路径上边的数目)的一个上界。(即树高)。当由MAKE-SET创建了一个单元集时,对应的树中结点的初始秩为0,每个FIND-SET操作不改变任何秩。当对两棵树应用UNION时,有两种情况,具体取决于根是否有相等的秩。当两个秩不相等时,我们使具有高秩的根成为具有较低秩的根的父结点,但秩本身保持不变。当两个秩相同时,任选一个根作为父结点,并增加其秩的值路径压缩。

2)路径压缩:

是在FIND-SET操作中,把查找路径上的每个结点都直接指向根结点。路径压缩并不改变结点的秩。关于路径压缩,看图理解,之间为FIND-SET操作前集合,之后为FIND-SET操作后集合。此时,查找路径上的每一个结点都直接指向根。
路径压缩代码实现方式有两种:递归式和非递归式。
1)递归方式
伪代码:
FIND-SET(x)


1  if x ≠ p[x]


2     then p[x] ← FIND-SET(p[x])


3  return p[x]


  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
并查集是一种常用的数据结构,主要用于解决集合合并和查找的问题。其中,查找操作可以带路径压缩,以优化查找效率。 具体来说,一个并查集由若干个集合构成。每个集合都有一个代表元素,用于表示该集合。初始时,每个元素都是一个单独的集合,其代表元素为自身。 并查集主要包含两个基本操作:查找和合并。 查找操作用于找到元素所在的集合,其实现通常采用递归或迭代方法实现路径压缩。递归方法可以简洁明了地实现路径压缩,但会造成函数调用开销较大;迭代方法则可以避免函数调用开销,但实现相对繁琐。 合并操作用于将两个集合合并为一个大集合,其实现通常采用按合并路径压缩两种优化方法。其中,按合并用于尽可能保持树的平衡,以避免树的高度过大,影响查找效率;路径压缩用于缩短树的高度,以进一步优化查找效率。 以下是一个带路径压缩的查找的并查集的实现示例: ``` const int MAXN = 1000005; int fa[MAXN]; int find(int x) { if (fa[x] == x) return x; return fa[x] = find(fa[x]); } void merge(int x, int y) { int fx = find(x); int fy = find(y); if (fx != fy) fa[fx] = fy; } ``` 其中,`fa`数组用于存储每个元素的父节点。初始时,`fa[i] = i`,表示每个元素自成一个集合。`find`函数用于查找元素所在的集合,并进行路径压缩;`merge`函数用于将两个集合合并为一个大集合。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值