第一章 概述
数据抽象是程序设计的中心内容,ADT(抽象数据类型)定义了数据取值范围和表现结构,以及对数据的操作集。可以定义ADT的描述规范:
ADT ADT名称 is
Data
描述数据的结构
Operations
构造函数
Inintial values: 用来初始化对象的数据
process: 初始化对象
操作1
Input: 用户输入的数值
Preconditions: 系统执行本操作前数据所必须的状态
Porcess: 对数据进行的动作
Output: 返回给用户的数据
Postconditions:系统执行操作后数据状态
操作2
。。。。。
操作n
。。。。。。
end ADT ADT名称
第二章 基本数据类型
c++流层次结构
第三章 抽象数据类型和类
1。c++提供特殊的语法来初始化数据成员:
Rectangle::Rectangle(float l,float w):length(l),width(w){}
第四章 群体类
1。结构化数据类型就是群体的例子,它存放数据并提供对数据元素的增删改操作。群体分为两大类:线性(有唯一的头元素和尾元素)和非线性。
线性群体中的元素按位置排列有序,可区分为第一个元素,第二个元素。。。。。。,按照访问类型分为:
直接访问:数组、记录、文件
顺序访问:文件、表、栈、队列、优先级队列
索引访问:字典(生活中的字典是由单词及其含义组成的群体)、哈希表(将存储的数据和主键联系起来的群体)
非线性群体不用位置顺序来标识元素。例如企业中的员工上下级关系。。。。。,分两类:
族(按层次区分的元素的集合):树、堆(树的特殊形式,根节点总是由值最小的元素占据)
组(元素间没有任何顺序关系):集合、图(描述点的集合即联结这些点的边的集合的数据结构)
2。算法分析
算法复杂度一般用O方法来表示,它通过分析算法的设计,包括算法中的比较,赋值等各种语句的次数来评价算法性能,这种方法独立于特定的计算机写,他用算 法处理的数据元素的个数n来衡量算法的计算复杂度。
一般有O(n2),O(nlgn),O(n)。。。。
第五章 栈和队列
1。
第十一章 树
1。层次:根到结点之间的路径的度量。根的层次是0;
树的深度:层次中的最大值。
快速访问是用树来存放数据的关键。
完全二叉树 满二叉树
实现遍历算法有时用到一个叫做visit的函数参数,它用来访问结点数据,来指定遍历过程中每个结点处要发生的动作。
2。二叉搜索树(详见二叉搜索树BinSTree)
第十二章 继承和抽象类
1。C++是用动态联编和虚成员函数的技术来支持多态性。动态联编允许系统中的不同对象对同一消息作出特定于其类型的响应,消息的接受者是在运行时动态确定的。
要使用多态性,必须在基类中声明虚成员函数。
当通过指针或引用访问时,C++根据指针或引用实际指向的对象决定调用哪个版本的函数,这一过程叫做动态联编。
一般地,如果类被用作基类,则一定要使其具有虚析构函数,及时建立一个什么也不做的析构函数。
2。迭代算子
抽象基类
template<class T>
class Iterator
{
protected:
// 是否已到表尾标志,由派生类维护
int iterationComplete;
public:
Iterator(void);
virtual void Next(void) = 0;
virtual void Reset(void) = 0
// 数据检索/修改方法
virtual T& Data(void) = 0;
// 是否已到表尾
virtual int EndOfList(void) const;
};
。。。。。。。。
3。存储具有同一数据类型的对象的集合被称为同构的;具有不同类型的对象的集合被称为异构的。
异构数组 异构链表
4。顺序表 SeqList 有序表 OrderedList:public SeqList
第十三章 高级非线性结构
1。二叉搜索树实现表并提供搜索时间为O(LOG2N)的搜索结构。但当树不是很平衡时效率会降低。ALV树是一种深度平衡树并保持了二叉树搜索树的优点。
2。基于数组的二叉树
虽然可以很自然地找到用树表示数组的方法(完全二叉树),但却没有直接将一颗普通二叉树表示为数组的方法。问题出现在那些与未使用的数组元素 相对应的空缺节点上。
3。二叉树的重要应用之一是作为抉择树,树中每个节点都代表一个具有两个可能去向的分支。
基于数组的树,它以数组的形式建立完全二叉树,在设计堆结构和有趣的竞赛排序时它们可以发挥极大的用处。
竞赛树 ==》 竞赛排序算法
堆 是节点间具有层次次序关系的完全二叉树,其中双亲值大于或等于其孩子值的,叫“最多堆”,否则叫”最小堆“。
4。用堆实现优先级队列,极大的提高了PQDelete方法的效率,因为它仅需要进行O(log2n)次比较,而与之相比,数组实现的比较次数是O(n)。
归并排序是对大型外部文件进行排序时的主要算法,如果数据被过滤或预处理到长归并段中,算法的效率会有所提高。
5。AVL树(详见AVLTree类)
理想情况下,树是平衡分布的,其高度为O(LOG2N),但对有些数据来说,二叉搜索树也可能是退化的,那时树高将是O(n),访问数据的速度将明显变慢。故AVL, 在AVL 中任一结点的两个子树的高度差最多为1。
AVL树的表示与二叉搜索树类似,其操作基本相同,但Insert和Delete方法除外,因为他们必须不断监控结点的左右子树的相对高度。为此扩展TreeNode对象的定 义,使之包括一个balanceFactor域,它为左右子树的高度差,其值必须在-1到1之间。
AVL树的价值取决于应用,因为在插入和删除结点时维护高度上的平衡需要额外开销。如果你的数据使二叉搜索树变成了退化树,则树在搜索元素方面的优势会丧失,AVL没有最坏的情况,因为这种结构接近于完全二叉树。find操作的执行时间是O(LOG2N)。平衡操作的复杂度表表明AVL树仅仅应当用在数据搜索占主要操作的场合。
树迭代算子(中序迭代算子)
6。图
深/广度优先 最短路径
无向图
第十四章 群体数据的组织
1。数组排序的基本算法(选择排序、冒泡排序、插入排序)
2。快速排序
3。哈希法
用一个函数将键值映射到一定的整数范围内,然后用整数值来访问数据,这种函数叫做哈希函数。哈希函数的性能取决于它产生的值是否均匀分布优酷0~n-1范围内。
哈希函数必须将键值映射为0到n-1 范围内的整数值,其设计必须减少冲突并保证执行效率,有几种方法:
除留余数法:两步,1是将键转换成整数值;2是用求余数运算符将这一值缩到0~n-1范围内。
平方取中法:将键转换为整数,求其平方值,然后从平方值的中间位置取连续的若干位。4。冲突的解决
线性探测开放寻址法:。。。。。。如果位置已经被填,算法就会绕表进行循环探测以找到表中第一个空位。
独立表链地址法:将哈希表定义为诸如链表或树一类的集合的数组,每个集合被称为桶bucket,他存放哈希映射到相同表位置的一组数据记录。
独立表链地址法一定要快于线性探测开发寻址法,它的缺点是需要为节点指针域分配额外空间;但总的来说,独立表链地址法的动态结构使他成为哈希的 首选方法。
5。哈希表类
6。二进制文件盒外部数据操作
用fstream.h中的类fstream进行二进制文件的I/O操作。
文本文件中包含的都是ASCII字符,各行用一系列换行符隔开,二进制文件则由数据记录构成,这些数据记录可以是单个字符(节),也可以是更复杂的 结构,在硬件一级,文件的数据记录是以定长数据块的形式存在硬盘上的。但从逻辑上看,我们将文件数据当做记录序列。文件系统允许直接访问单独的 数据记录,使得我们可以将文件看做外部记录的数组。在数据被读入或写出的过程中,系统维护一个指向当前位置的指针。
BinFile类
7。辞典(详细看)
要实现非常复杂的辞典概念实际上也比较容易;选择一个集合类存储KeyValue对象。可以用OrderList,BinTree和AVLTree存储有序的键值对。若要存储无序的键-值队,可以用集合类SeqList和HashTable。