抽象数据类型仅仅是一个概念名词吗?你会借助抽象数据结构解决问题吗?
0,抽象数据类型
我们在学习数据结构时,一般情况下对于 “抽象数据类型” 这个知识点完全没有放在心上,最多把他当做一句概念给它背了下来。下面就此进行论述。
抽象数据类型(Abstract Data Type,ADT)是指一个数学模型以及在此数学模型上的一组操作。抽象数据类型需要通过固有的数据类型来实现。对于一个抽象数据类型进行定义时,必须给出抽象数据类型名称和包含的运算名称及其功能描述。一旦定义了一个抽象数据类型并具体实现,程序设计中就可以像使用基本数据类型那样,十分方便的使用该抽象数据类型。具体什么意思?待会儿看下面的例子。
例子:定义单个集合的抽象数据类型ASet,其中所有元素为正整数,包含创建一个集合、输出一个
集合和判断一个元素是否为集合中元素的基本运算。
再此基础上再定义两个集合运算的抽象数据类型BSet ,包含集合的并集、差集和交集运算。
1,抽象数据类型的定义
抽象数据类型Aset的定义如下:
抽象数据类型BSet 的定义如下:
看了上面的对抽象数据类型的定义,是不是感觉求解问题一下子清晰了不少呢?接下来只需要我们用所学的语言具体实现其功能即可。
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 环境下运行结果:
vs2013 环境下运行结果:
得到结果后,我们不妨结合下图细想一下整个过程的构思、实现和调用,好好的理解一番!