目录
抽象数据类型(Abstract Data Type,ADT)
(数据结构的个人笔记,学习自《大话数据结构》和《数据结构与算法基础(青岛大学-王卓)》,BV1nJ411V7bd)
基本概念和术语
数据
- 是描述客观符号,是计算机中可以操作的对象是能被计算机识别,并输入给计算机处理的符号集合
- 不仅仅包括整型、实型等数值类型,还包括字符及声音、图像、视频等非数值类型(MP3是声音数据、图片是图像数据)
这里说的数据,其实就是符号,而且这些符号必须具备两个前提
- 可以输入到计算机中
- 能被计算机程序处理
数据元素
组成数据的、有一定意义的基本单位,在计算机中通常作为整体处理
人类中的数据元素:人
畜类中的数据元素:牛、马、羊等
数据项
一个数据元素可以由若干个数据项组成
这里【学号】、【姓名】、【性别】、【籍贯】、【专业】 都是数据项
数据项是数据不可分割的最小单位
数据对象
性质相同的数据元素的集合,是数据的子集
(性质相同指数据元素具有相同数量和类型的数据项,如人都有姓名、性别)
数据结构
相互之间存在一种或多种特定关系的数据元素的集合
逻辑结构
指数据对象中数据元素之间的相互关系
集合结构
集合结构中的数据元素,除了同属于一个集合外,它们之间没有其他关系
线性结构
线性结构中的数据元素之间,是一对一的关系
树形结构
树形结构中的数据元素之间,存在一种一对多的层次关系
图形结构
图形结构的数据元素,是多对多的关系
物理结构(存储结构)
指数据的逻辑结构在计算机中的存储形式
顺序存储结构
把数据元素存放在地址连续的存储单元里,其数据间的逻辑关系和物理关系一致
链式存储结构
把数据元素存放在任意的存储单元里,这组存储单元可以连续,也可以不连续
(数据元素的存储关系并不能反映去逻辑关系,因此需要用一个指针存放数据元素的地址,通过地址找到相关联的数据元素的位置)
数据类型
指一组性质相同的值的集合,及定义在此集合上的一些操作的总称
- 原子类型:不可再分解的基本类型,包括整型、实型。字符型
- 结构类型:由若干个类型组合而成,可再分解。如整型数组由若干整型数据组成
抽象数据类型(Abstract Data Type,ADT)
指一个数学模型及定义在该模型上的一组操作
ADT 抽象数据类型名{
Data
数据元素之间逻辑关系的定义
Operation
操作1
初始条件
操作结果描述
操作2
……
操作n
……
}ADT 抽象数据类型名
基本操作的定义说明-参数表:
赋值参数:只为操作提供输入值
如:
求圆的面积
area(r)
/*area - 操作的名字
r - 参数,圆的半径*/
求乘方
power(x,y)
/*求 x 的 y 次方*/
引用参数
以 & 打头,除可提供输入值外,还将返回操作结果
如:
对一个图形进行缩放
scale(&G, n)
/*对图形 G 进行缩放 n 倍的操作
加上 & 可以返回操作结果*/
初始条件
描述操作执行之前数据结构和参数应满足的条件,若不满足,则操作失败,并返回相应出错信息。若初始条件为空,则省略
操作结果
说明操作正常完成之后,数据结构的变化状况和应返回的结果
抽象数据类型定义举例:Circle的定义
ADT Circle { /*ADT开头,定义的抽象数据类型叫作Circle*/
数据对象:D = { r,x,y | r,x,y 均为实数 }
数据关系:R = { < r,x,y > | r 是半径, < x,y >是圆心坐标 }
基本操作:
creatCircle( &C,r,x,y ) /*用 r,x,y 构造一个圆,通过 C 返回结果*/
操作结果:构造一个圆
double Area( C ) /*求圆的面积*/
初始条件:圆已存在
操作结果:计算面积
double Circumference( C ) /*求圆的周长*/
初始条件:圆已存在
操作结果:计算周长
…… /*如果有其他操作,继续写*/
} ADT Circle
实现
#include <stdio.h> #include <math.h> #define M_PI 3.14 // 定义圆的数据对象 typedef struct { double r; // 半径 double x; // 圆心的x坐标 double y; // 圆心的y坐标 } Circle; // 构造一个圆 void createCircle(Circle* c, double r, double x, double y) /* Circle* c是一个指向Circle结构体的指针。 r,x,y是接收传参的形参 c是结构体指针,用->连接成员变量,然后将接收的值赋给r,x,y */ { if (c != NULL) // 传入指针时,考虑是否为空指针 { c->r = r; c->x = x; c->y = y; } } // 计算圆的面积 double Area(Circle c) // 因为是形参,用结构体变量.成员变量的操作 // 指针可以改变变量的值,所以返回类型是void,这里是形参,要写返回类型 { return M_PI * c.r * c.r; } // 计算圆的周长 double Circumference(Circle c) { return 2 * M_PI * c.r; } // 主函数,用于测试 int main() { Circle C; double r = 5.0; double x = 1.0; double y = 2.0; // 构造圆 createCircle(&C, r, x, y); // 计算并打印圆的面积和周长 printf("Circle Area: %f\n", Area(C)); //Area(C)不加&传参 printf("Circle Circumference: %f\n", Circumference(C)); return 0; }
复数的定义
ADT Complex {
D = { r1,r2 | r1,r2 都是实数 }
S = { < r1,r2 > | r1 是实部,r1是虚部 }
Assign( &Z,v1,v2)
初始条件:空的复数 Z 已存在
操作结果:构造复数 Z,r1,r2 分别被赋以参数 v1,v2的值
GetReal( Z,&RealPart )
初始条件:复数已存在
操作结果:用 RealPart 返回复数 Z 的实部值
GetImage ( Z,&ImagPart )
初始条件:复数已存在
操作结果:用 ImagPart 返回复数 Z 的虚部值
Destroy( &Z )
初始条件:复数 Z 已存在
操作结果:复数 Z 被销毁
}ADT Complex
#include <stdio.h> #include <stdlib.h> // 定义复数的结构体 typedef struct { double real; // 实部 double imag; // 虚部 }Complex; // 构造复数 void Assign(Complex* Z, double v1, double v2) { if (Z != NULL) { Z->real = v1; Z->imag = v2; } } // 获取复数的实部 void GetReal(Complex Z, double* RealPart) { if (RealPart != NULL) { *RealPart = Z.real; } } // 获取复数的虚部 void GetImage(Complex Z, double* ImagPart) { if (ImagPart != NULL) { *ImagPart = Z.imag; } } // 销毁复数 void Destroy(Complex* Z) { // 在C语言中,结构体的销毁通常不需要特别的操作,因为它们通常存储在栈上或静态分配。 // 如果是动态分配的内存,则需要释放内存。 if (Z != NULL) { // 如果有动态分配的资源,可以在这里释放 // free(Z); // 如果Z是动态分配的指针 } } int main() { Complex Z; double realPart, imagPart; // 构造复数 Assign(&Z, 1.0, 2.0); // 获取实部和虚部 GetReal(Z, &realPart); GetImage(Z, &imagPart); // 输出实部和虚部 printf("复数的实部是: %f\n", realPart); printf("复数的虚部是: %f\n", imagPart); // 销毁复数 Destroy(&Z); return 0; }