第八章(ADT不相交集)

输入数据是N个集合的类,每个集合含有一个元素。
每个集合都有一个不同的元素,从而Si∩Sj= Ø;使得这些集合不相交。

此时,有两种运算允许运行。find()返回包含给定元素的集合的名字,第二种是添加关系,如果想要添加关系(a,b)

首先查看a和b是否已经有关系,对a和b执行find并检验它们是否在一个集合,若不在一个集合,使用并运算Union(),这种运算把含有a和b的集合合并为一个集合。

基本数据结构:用一个数组来记录元素的父节点。数组中的每个成员P[i]表示元素i的父亲,集合的名字有根处的节点给出。
若P[i]为负值,表示该集合的规模,如-1为集合中有一个元素。

为了执行两个集合的Union运算,使一个节点的根指针指向另一个树的根节点。

对元素X的一次Find(X)操作通过返回包含X的树的根而完成。

#include<stdio.h>
#define MAXNUM 100
//初始化P数组

void Initilalize(int P[],int N) {
	//N为节点的个数
	int i;
	for (i = 0; i < N; i++)
		P[i] = -1;
}

// 查找元素X 属于的集合
int Find(int P[], int X)
{
	if (P[X] < 0)
	{
		return X; // 如果X中内容为负值,代表X就是根节点
	}
	else
	{
		return P[X] = Find(P, P[X]); // 继续查找,并返回查找到的集合,进行路径压缩
	}
}

void Union(int x,int y,int P[]) {
	int x_root, y_root;
	x_root = Find(P, x);
	y_root = Find(P, y);
	if (x_root == y_root) // 属于同一个集合,什么也不做
	{
		return;
	}
	else
	{
		if (P[x_root] < P[y_root]) // 按集合中的规模大小进行合并,x_root集合大
		{
			P[x_root] += P[y_root];	// x_root集合更新规模
			P[y_root] = x_root;		//y_root集合更新根节点
		}
		else
		{	//y_root的集合大
			P[y_root] += P[x_root];	// y_root集合更新规模
			P[x_root] = y_root;		// x_root集合更新根节点
		}
	}
}

int CheckCycle(int P[], int x, int y)		// 判断两个顶点是否相连,不相连合并集合
{
	int x_root, y_root;
	x_root = Find(P, x);
	y_root = Find(P, y);
	if (x_root == y_root)
	{
		return 1;
	}
	else
	{
		Union(x_root, y_root, P);
		return 0;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值