并查集算法

本文详细介绍了等价类的概念,并以此为基础解释了并查集的基本原理。通过数组和链表两种方式实现了并查集,包括查找和合并操作。适用于初学者理解并查集的工作机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

想要弄明白什么是并查集首先要明白什么是等价类
我们说关系R是一个等价关系当且满足以下条件:
1.对于所有的a∈U,有(a,a)∈R时(关系是自反的)
2.(a,b)∈R,当且仅当(b,a)∈R(关系是对称的)
3.若(a,b)∈R且(b,c)∈R,则有(a,c)∈R(关系是传递的)
比如R={(1,11),(7,11),(2,12),(12,8),(11,12),(3,13),(4,13),(13,14),(14,9),(5,14),(6,10)}
根据等价关系和对称关系我们发现里面包含三个等价类。
{1,2,7,8,11,12},{3,4,5,9,13,14},{6,10}
在每个等价类里面知道了其中一个元素,就能根据等价关系R推出等价类里面的其他元素。
并查集主要由一个整数型的数组和两个函数构成。数组pre[]记录了每个点的前导点是什么,函数find是查找,join是合并。

以下为使用数组实现并查集算法

int pre[1000];
int find(int x) //查找根节点
{
	int r=x ;     //委托r去找根节点
	while(pre[r]!=r) //如果r是顶节点,那么pre[r]就是它自己
	r=pre[r];         //不断地向上方进行查找,知道找到根节点
    return r;
}
void join(int x,int y)
{
	int fx=find(x),fy=find(y);
	if(fx!=fy)        //如果两个等价类的根节点不同,则合并等价类。
		pre[fx]=fy;
}

以上参考与该博主的博客,更详细的解答请移步这里:https://blog.youkuaiyun.com/the_best_man/article/details/62416938

以下为链表的实现:

#include<iostream>
#include<stdio.h>
#include<set>
#define N 50001

using namespace std;

set<int> s;
struct Point
{
	int x;//用来存储父类点
	Point *root;//用来存储链表根节点的地址
	Point *next;//用来存储下一个节点的地址
	Point *tail;//用来存储链表尾部节点的地址
}p[N];

int n;

void makeSet()//初始化序列集
{
	for(int i=1;i<=n;i++)
	{
		p[i].root=&p[i];//初始化时自己的根节点就是自己
		p[i].x=i;//初始时根就是自己
		p[i].next=NULL;//next没有指向其他
		p[i].tail=&p[i];//尾部指针就是自己
	}
}
int findRoot(int x)
{
	return p[x].root->x;
}

void update(Point* root,Point* p)
{
	while(p!=NULL)//将P链表的根节点更新为root的根节点
	{
		p->root=root;
		p=p->next;
		
	}
	while(root!=NULL)//将root链表的尾节点更新为p节点的尾节点。
	{
		root->tail=p->tail;
		root=root->next;
	}
	root->tail->next=p;//将两个链表链接起来
	root->tail=p->tail;
	
}
void merge(int a,int b)
{
	Point* ra=p[a].root;
	Point* rb=p[b].root;
	if(ra!=rb)

	update(rb,ra);	
}

以上代码我在原博主代码基础上进行了简化,源代码链接点击这里:https://blog.youkuaiyun.com/jiakai0419/article/details/7518525

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值