(案例复盘)用抽象数据结构解决问题【集合的交、并、补】

抽象数据类型仅仅是一个概念名词吗?你会借助抽象数据结构解决问题吗?

0,抽象数据类型

我们在学习数据结构时,一般情况下对于 “抽象数据类型” 这个知识点完全没有放在心上,最多把他当做一句概念给它背了下来。下面就此进行论述。

抽象数据类型(Abstract Data Type,ADT)是指一个数学模型以及在此数学模型上的一组操作。抽象数据类型需要通过固有的数据类型来实现。对于一个抽象数据类型进行定义时,必须给出抽象数据类型名称和包含的运算名称及其功能描述。一旦定义了一个抽象数据类型并具体实现,程序设计中就可以像使用基本数据类型那样,十分方便的使用该抽象数据类型。具体什么意思?待会儿看下面的例子。

例子:定义单个集合的抽象数据类型ASet,其中所有元素为正整数,包含创建一个集合、输出一个
集合和判断一个元素是否为集合中元素的基本运算。 
再此基础上再定义两个集合运算的抽象数据类型BSet ,包含集合的并集、差集和交集运算。

1,抽象数据类型的定义

抽象数据类型Aset的定义如下:

img

抽象数据类型BSet 的定义如下:

img
看了上面的对抽象数据类型的定义,是不是感觉求解问题一下子清晰了不少呢?接下来只需要我们用所学的语言具体实现其功能即可。

2,设计存储结构

然后我们在设计一个存储结构 :用整型数组存放Aset 中的数据元素集合D ,用一个整型变量 length 表示数组中的实际元素个数。如下,设计一个集合结构体类型:

typedef struct{		//集合结构体类型
	int data[MaxSize];	//存放集合中的元素
	int length;	//存放集合中实际元素个数
}Set;	//将集合结构体用新类型名Set表示

以上就是采用 Set类型的变量存储一个集合。

3,设计抽象数据结构中运算算法

下面我们就按顺序先看 Aset 抽象数据类型中的运算算法对应的几个函数:

//1,由数组a创建集合s
void cset(Set &s, int a[], int n){
	for (int i = 0; i < n; i++){
		s.data[i] = a[i];
	}
	s.length = n;
}

//2,输出集合s中的所有元素
void dispset(Set s){
	for (int i = 0; i < s.length; i++)
		printf("%d  ", s.data[i]);
	printf("\n");
}

//3,判断e是否在集合s 中
int inset(Set s, int e){
	for (int i = 0; i < s.length; i++)
		if (s.data[i] == e)
			return 1;
	return 0;
}

接着,我们再看Bset 抽象数据类型中的运算算法:

//1,求集合并集
void add(Set s1, Set s2, Set &s3){
	int i;
	for (i = 0; i < s1.length; i++)	//将集合s1的所有元素复制到s3中
		s3.data[i] = s1.data[i];
	s3.length = s1.length;
	for (i = 0; i < s2.length;i++)
		if (!inset(s1, s2.data[i])){	//将s2中不在s1中出现的元素复制到s3中
			s3.data[s3.length] = s2.data[i];
			s3.length++;
	}
}

//2,求集合的差集
void sub(Set s1, Set s2, Set &s3){
	s3.length=0;
	for (int i = 0; i < s1.length; i++)//将s1中不出现在s2中的元素复制到s3中
		if (!inset(s2, s1.data[i])){
			s3.data[s3.length] = s1.data[i];
			s3.length++;
		}
}

//3,求交集
void intersection(Set s1, Set s2, Set &s3){
	s3.length = 0;
	for (int i = 0; i < s1.length;i++)//将s1中出现在s2中的元素复制到s3中
		if (inset(s2, s1.data[i])){
			s3.data[s3.length] = s1.data[i];
			s3.length++;
	}
}

4,设计主函数

在所有的基本运算设计好后,在设计相关的主函数如下:

//设计主函数
int main(){
	int a[] = { 1, 4, 2, 6, 8 };
	int b[] = { 2, 5, 3, 6 };
	Set s1, s2, s3;
	cset(s1, a, 5);
	cset(s2, b, 4);
	printf("集合s1:");
	dispset(s1);
	printf("集合s2:");
	dispset(s2);
	add(s1, s2, s3);
	printf("集合s1和s2的并集:");
	dispset(s3);
	sub(s1, s2, s3);
	printf("集合s1和s2的差集:");
	dispset(s3);
	intersection(s1, s2, s3);
	printf("集合s1和s2的交集:");
	dispset(s3);
	system("pause");
	return 0;
}

此时我们将上述所写程序进行编译运行,会得到如下结果:

vscode 环境下运行结果:
vscode环境下运行结果
vs2013 环境下运行结果:
VS2013环境下运行结果

得到结果后,我们不妨结合下图细想一下整个过程的构思、实现和调用,好好的理解一番!
在这里插入图片描述

  • 7
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
1. 本演示程序中,集合元素限定为数字,大小由用户输入。集合中数字顺序不限,且一旦出现重复字符或非法字符,程序能自动滤去。输出的运算结果中将不含重复数字或非法字符,且按照从小到大的顺序输出。<br>2. 演示程序以用户和计算机的对话方式执行,即在计算机上显示“提示信息”之后,由用户在键盘上输入演示程序中规定的运算命令;相应的数据输入和运算结果显示在其后。<br>3. 程序执行的命令包括:<br>(1)构造集合1;(2)构造集合2;(3)判断某数是否为集合元素;(4)添加元素;(5)删除元素;(6)求并集(存入集合1中);(7)求集(存入集合3中);(8)输出集合1;(9)输出集合2;(0)退出。<br>“构造集合1”和“构造集合2”时,需以整型数字形式键入集合元素。<br><br>为实现上述程序功能,以线性链表表示集合。为此,需要两个抽象数据类型:线性表和集合。<br>1. 线性表的抽象数据类型定义为:<br> ADT LinkList{<br> 数据对象:D={ | IntSet,i=1,2,…,n,n 0}<br> 数据关系:R1={< , >| , D, < ,i=2,…,n}<br> 基本操作:<br> InitList(*L)<br> 操作结果:构造一个空的线性链表L。<br> IsElement(*L,e)<br> 初始条件:线性表L已存在。<br> 操作结果:若e是L的数据元素,返回1,否则返回0。<br> Append(*L,e)<br> 初始条件:线性表已存在。<br> 操作结果:按照由大到小的顺序往线性表里插入元素e,不允许重复元素。<br> Delete(*L,e)<br> 初始条件:线性表已存在。<br> 操作结果:在L中删除元素e。<br> }ADT LinkList<br>2. 集合抽象数据类型定义为:<br> ADT LinkSet {<br> 数据对象:D={ | IntSet,i=1,2,…,n,n 0}<br> 数据关系:R1={}<br> 基本操作:<br> CreatSet(*L)<br> 初始条件:s为整型数组。<br> 操作结果:生成一个由s中数字构成的集合。<br> Union(*S1,*S2)<br> 初始条件:集合S1和S2存在。<br> 操作结果:生成一个由S1和S2的并集构成的集合,返回到S1。<br> Intersection (*S1,*S2)<br> 初始条件:集合S1和S2存在。<br> 操作结果:生成一个由S1和S2的集构成的集合,返回到S1。<br> PrintSet (*S)<br> 初始条件:集合S已存在。<br> 操作结果:依次显示集合S中的全部元素。<br> }ADT LinkSet<br><br><br>带菜单<br>Turbo c 3.0编写
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阔升

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值