3. 抽象数据类型(ADT)
a. 什么是类型?
§ 类型特指两类信息:属性和操作
b. 如何定义一种新类型?
i. 提供类型的属性和相关操作的抽象描述(ADT)
□ (你得告诉其他人新类型如何区分,如何定义,可以进行什么操作?)
ii. 开发一个实现ADT的编程接口
□ 对这个类型进行储存方式的确定,以及该如何进行某些操作
iii. 编写代码实现接口
□ 这是一个代码细节的实现,由创建者完成,使用者无需关心细节
c. 示例(C primer plus p1320)
i. 建立抽象(确定新类型的属性和操作)
1) 类型名:简单链表
2) 类型属性:可以存储一些项
3) 类型操作:初始化链表为空、确定链表为空、确定链表已满、确定链表中的项数、在链表末尾添加项、遍历链表并处理、清空链表等
ii. 建立接口
1) 要描述如何表示数据
2) 要描述实现ADT操作的函数
3) 其实就是描述函数原型、数据存储形式
4) 这部分内容供使用者直接调用
iii. 使用接口
1) 在这一层级,使用建立的接口,去构建主程序
2) 主程序调用新的数据类型以及调用数据类型对应的操作
3) 最终完成目的
iv. 实现接口
1) 在这一层级,要完成与操作相关的函数的实现细节
2) 这一层通常会被隐藏----称为数据隐藏
4. 队列ADT(这是一种从抽象到具象,再到应用于实际问题的编程方式)
a. 队列的一般定义:队列是一种特殊的链表数据结构,先入先出,只能在链表的末尾添加新项,只能在链表的开头移除项
b. 定义对列抽象数据类型(建立抽象)
i. 类型名:队列
ii. 类型属性:可以储存一些项
iii. 类型操作:初始化队列为空、确定队列已满、确定队列中的项数、在队列末尾添加项、在队列开头删除或恢复项、清空队列
c. 定义接口(放在.h头文件中)
i. 队列的成员称为Item、队列称为Queue,这些名称的细节定义放在实现接口部分
ii. 主要是负责描述函数原型
d. 实现接口
i. 实现接口的数据表示(也就是要选择用什么样基本数据类型构成可以满足我们抽象定义的队列的属性和操作)前面的工作已经确定了队列的名称、成员,现在的工作就是将他们实现出来
1) 数组方式
2) 环形数组构成环形队列方式
3) 使用链表的方式
® 使用链表在删除首项时只要将头指针指向新的首元素即可
ii. 实现接口的操作函数
1) 实现操作的函数,要注意只使用接口函数来处理数据类型
e. 测试队列
i. 编写一个小程序测试该队列的所有函数
5. 链表和数组
a.
b. 数组和链表在添加和删除元素时差异很大
i. 数组插入和删除元素时,必须移动其他元素腾出空位插入新元素
ii. 链表插入新元素和删除元素时,只需要更改两个元素的指针或更改一个指针并释放内存即可
c. 什么是随机访问
i. 对于数组,可以通过下标,直接访问数组中的任何一个元素---随机访问
d. 什么是顺序访问
i. 例如链表,只能从链表头开始访问,逐个按照顺序访问元素---顺序访问
e. 顺序查找和二分法查找
i. 从列表的开头开始按照顺序查找
ii. (改进)先将列表排序,然后如果查找到到应该排在待查找目标的后面,就不必再查找了
iii. (更好的算法)二分法查找
□ 二分法查找只是适用于数组,不适用于链表。因为链表不能直接访问中间项
iv. 综上:链表适合经常插入和删除数据;基于数组的二分法查找适合经常要查找的数据
6. 既支持经常插入和删除项又支持频繁查找项的算法—二叉查找树
a.
b. 二叉树的每个节点都包含一个项和两个指向其他节点(子节点)的指针
c. 左节点的项在父节点的项的前面;右节点在父节点的项的后面