数据结构-不相交集ADT

若对于每一对元素(a,b),a、b属于S,aRb或者为true或者为false,则称在集合S上定义关系R。如果aRb是true,那么我们说a与b有关系。

等价关系是满足下列三个性质的关系R:

  1. 自反性:对于所有的a属于S,aRa;
  2. 对称性:aRb当且仅当bRa;
  3. 传递性:若aRb且bRc,则aRc; ’
一个元素a属于S的等价类是S的一个子集,它包含所有与a有关的元素。

所以,不相交集实质上就是各个等价类组成的集合。

不相交集允许的运算:Find和Union。

Find:返回包含给定元素的集合(即等价类)的名字;

Union:添加关系aRb,若a、b不在同一个等价类中,则使用Union把a、b合成一个等价类。

不相交集的类型声明:

#include<stdio.h>


#define NumSets 1000

typedef int DisjSet[NumSets+1];
typedef int SetType;
typedef int ElementType;

void Initialize(DisjSet s)
{
	int i;
	for (i = NumSets; i > 0; i++)
		s[i] = 0;
}

不相交集运算的实现:

void SetUnion(DisjSet s, SetType root1, SetType root2)
{
	s[root2] = root1;
}

SetType Find(ElementType x, DisjSet s)
{
	if (s[x] <= 0)
		return x;
	else
		return Find(s[x], s);
}

下面是对算法的改进:

灵活求并的算法:

分为按高度和按大小求并。

  • 按大小求并:总让较小的树成为较大的树的子树,每个根的数组元素包含其树大小的负值;
  • 按高度(秩)求并:浅的树成为深的树的子树。只有两棵树相等深度求并时,树的高度才增加。每个根的数组元素包含其树高度的负值。
按高度求并:

void SetUnion(DisjSet s, SetType root1, SetType root2)
{
	if (s[root2] < s[root1])
		s[root1] = root2;
	else
	{
		if (s[root1] == s[root2])
			s[root1]--;
		s[root2] = root1;
	}
}

基于路径压缩的Find算法:

路径压缩只在Find操作执行期间执行,与Union操作无关。路径压缩的效果为:从结点x到根的路径上的每一个结点,都使它的父节点变为根。由此对这些结点未来的快速访问将由于花费额外的工作来进行路径压缩而得到补偿。

SetType Find(ElementType x, DisjSet s)
{
	if (s[x] <= 0)
		return x;
	else
		return s[x]=Find(s[x], s);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值