用于不相交集合的数据结构(并查集)

一,两个重要操作:(1)找出给定元素所属的集合
(2)合并两个集合
二,原理:保持一组不相交的动态集合s={s1,s2,…sk}。每个集合通过一个代表来识别,代表即集合中的某个元素
三,操作
(1)MAKE-SET(X):建立一个新的集合,其唯一成员就是x(因各集合是不相交的,故要求x没有在其他集合中出现过)
(2)UNION(X,Y):将包含x和y的动态集合合并为一个新的集合
(3)FIND-SET(X):返回一个指针,指向包含x的唯一集合代表
四,不相交集合森林
(1)用有根树来表示集合,树中的每个节点都包含集合的一个成员,每个树表示一个集合。
(2)每个成员仅指向其父节点。每个树的根包含了代表,并且是他自己的父节点。
(3)改进方法:
a)按秩合并:使包含较少节点的树的根指向包含较多节点树的根
对每个结点,用秩表示节点高度的一个上界(即根节点到其某一后代叶子节点的最长路径上变得数目)
b)路径压缩: 是查找路径上的每个节点都指向根节点。(简单,有效)不改变节点的秩。
五,伪代码

P[X]表示x的父节点 RANK[x]存放x节点的秩

MAKE-SET(X)  //创建一个单元素集合,并初始秩为0
P[X]<-X
RANK[X]<-0

UNION(X,Y)  //合并两个集合
LINK(FIND-SET(x),FIND-SET(Y))

LINK(X,Y)  //按秩合并
IF RANK[X]>RANK[Y]
      THEN P[Y]<-X
      ELSE P[X]<-Y
      IF RANK[X]=RANK[Y]
        THEN RANK[Y]=RANK[Y]+1


FIND-SET(X)//FIND-SET是一种两趟方法:一趟沿查找路径上升直至找到根 另一趟沿查找路径下降,以便更新每个节点,使之指向根·
IF X!=P[X]
   THEN P[X]<-FIND-SET(P[X])
   RETURN P[X]

六用c++语言实现

int pre[maxn];
int rank[maxn];
int findset(int x)    //带路径压缩 
{
	if(pre[x]==x)
	  return x;
	else 
		return pre[x]=findset(pre[x]);
	
	}
void link(int x,int y)  //按秩的连接算法 
{
	if(rank[x]>rank[y])
	{
		pre[y]=x;
	}
	 else{
	      pre[x]=y;
	      if(rank[y]==rank[x])
	      rank[y]=rank[y]+1;
	  }
}

void makeset(int x)
{
	pre[x]=x;
	rank[x]=0;
}
void UNION(int x,int y)
{
	int xx=findset(x);
	int yy=findset(y);
	if(xx!=yy)
	  link(xx,yy);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值