开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第19天,点击查看活动详情
✨欢迎关注🖱点赞🎀收藏⭐留言✒
🔮本文由京与旧铺原创,csdn首发!
😘系列专栏:java学习
💻首发时间:🎞2022年12月10日🎠
🀄如果觉得博主的文章还不错的话,请三连支持一下博主哦
🎧作者是一个新人,在很多方面还做的不好,欢迎大佬指正,一起学习哦,冲冲冲
🎀🎀🎀今日分享:这一年大概是我长这么大,最难熬的一年,也是让我成长最多的一年,感谢生活赐予我一场惊慌失措,但愿以后抬头由阳光
🐱💻导航小助手
2.2实现并查集查找根结点
在并查集中,由于对于非根结点,它指向的结点都不会是本身,严格来说没有进行优化前,某个元素会指向同一集合中的另外一个元素,就如下图所示,可以理解为一棵树:
所以并查集在查找的时候,如元素
6,它指向3,我们可以先到3这个位置,通过3这个位置进而找到根结点。
对应的代码片段如下:
int find(int x) {
while (x != p[x]) {
x = p[x];
}
return x;
}
//递归形式
int find(int x) {
if (x == p[x]) return x;
return find(p[x]);
}
当树的高度比较高的时候,效率就比较低,数据大一点就会超时,因此我们可以做一个优化,就是在搜索根结点的时候,没找到一次根结点,我们就将所寻找路径上面所有元素都指向根结点,这样就与上面举例相同了,这个优化的过程也叫做路径压缩。
这四个小组就对应着几个不同的集合,因为每个组员是记得他们的组长是谁的,所以我们可以通过询问组员就知道他们组长,进而就能知道该成员是哪一组的。
那么对应到并查集,我们知道当数组下标与元素相等时,该下标就是组长的编号也就是根结点,那我们可以先判断该元素的下标是否与存储的元素相同,如果不同,则跳到储存元素作为下标的位置,继续查找,找到根结点后,将搜索路径上的每个元素都置为该根结点的下标。
代码:
//查找某元素的根
int find(int x)
{
if (x != p[x]) p[x] = find(p[x]);
return p[x];
}
2.3通过两个不同集合元素合并两个集合
这个就很简单了,我们只需要找到两个不相交集合元素的根结点,然后将其中一个根结点指向另外一个集合即可。
实现代码:
//union合并两个集合
void union(int a, int b)
{
int ar = find(a);
int br = find(b);
if (ar == br) return;
p[br] = ar;
}
到这里我们的一个并查集就实现完成了,下面通过一道模板题,来展示完整代码与验证。