学习数据结构这门课程至少要经历三个过程,方可真正的掌握这门课程,得到一个满意的成绩。这个过程简单来说就是三个字:活→死→活。
首先,是一个学“活”的过程,就要要求我们对书中的每一个算法,能够在脑海中建立起相应的模型,而不是死板的算法。比如树的遍历非递归算法,在入栈与出栈的过程
中,我们就要在脑海中形成访问树每个结点的过程,真正掌握住这个算法。这样,全书复习下来,你的脑海中就有了整个数据结构的模型概念,对任何一个陌生的算法,将不感到
生疏和害怕。
有些同学到了此处就觉得数据结构已经学好,可以万事大吉了,其实这还远远不够,如果参加考试,往往会拿不到高分,甚至还会纳闷,为何自己数据结构学的这样好,成
绩却不尽如人意,因此产生了批卷老师判错的想法。所以第二个过程,就是一个学“死”的过程,这个过程要求,要记住书中的算法(功利一点就是要背诵会所报考学校的考试要
求的算法)。有的学校有别的特殊要求,也一并背会。如上海交通大学喜欢考平均复杂度的分析这样的题目,我们在书上可以找到这样的分析一共十一个,全部背会,就免去了在
考场上分析的麻烦,如果连答案都能记住,那么,也不会因为粗心失分了。这一过程也许有些枯燥,但却是最重要的过程,比如说背会了树的后序遍历非递归,遇到了像求某个结
点的所有祖先,两个结点的共同祖先这样的题,不用想,直接套用。这样才是考试的高分的关键:在考场上,遇到考题,不用思考,直接从脑海中找匹配的算法,直接引用。有了第二个过程的辛苦,我们就可以得到一个比较高的分数了,如果还想提高,就
要进行第三个过程,再学“活”的过程。这一个过程中就要要求我们,在第二步的基础上,多进行思考,看看有哪些算法有共性,比如说:树的前序非递归遍历算法和图的深度优
先遍历算法是不是类似啊,有些什么不同,有些什么相同,为什么会相同;森林转化为二叉树和图的生成树的算法也是这样,等等。总结出这种共性,这样就能正确有效的记忆算
法,同时,遇到难题不至于慌乱,能够从容下手解题。
对于总结共性问题上,这里举一小个例子,(呵呵,我当初总结出这个,并且和kaoyan.com斑竹一具讨论确定后三天,就在2002年交大第一题考出类似东东)比如树的遍
历,不管是递归还是非递归,也不管是线索树,还是头结点有父母信息的树,它的遍历其实就是一个寻找到遍历的第一个结点,然后再寻找它的后继结点的过程,我们归纳到此处,就可以试着总结一下三种
遍历的后继结点是哪个,有几种情况:
对于前序遍历,它的后继如下:
(1)若有左孩子,则后继是左孩子;
(2)若无左孩子,有右孩子,则后继是右孩子;
(3)若既无左孩子,又无右孩子,则是一片叶子;再讨论:
(a)若是其父母的左孩子,且父母有右孩子,则后继是父母的右孩子。
(b)若是其父母的左孩子,且父母无右孩子;
(c)若是其父母的右孩子。
b,c都表示这是某个节点的左子树前序遍历的最后一个节点,则需要找第一个有右子树的“左祖先”(定义“左祖先”,即找第一个使得当前节点在这个祖先的左子树上),
然后后继就是这个祖先的右孩子。
对于中序遍历,它的后继如下:
(1)如有右孩子,后继是右孩子的最左下节点;
(2)若无右孩子,且是父母的左孩子,则后继就是父母;
(3)若无右孩子,且是父母的右孩子,则一直上溯到第一个“左祖先”(定义如前)则后继就是这个祖先。若无这样的祖先,说明已经遍历完毕。
对于后序遍历,它的后继如下:
(1)若是父母的右孩子,则后继是父母;
(2)若是父母的左孩子,且父母无右子树,则后继是父母;
(3)若是父母的左孩子,父母有右子树,则后继是父母右子树的最先访问到的节点(指向父母的右子树后,一直往左,若不行的话,往右一步,一直到叶子)
总结完了,想一想,我们还能得到哪些提示?经常有一类型题目,要求求某个结点的直接前驱。其实求前序遍历的前驱和求后序遍历的后继是一样的,只不过把左换成右而
已,前序遍历的求后继和后序遍历的求前驱、中序遍历的求前驱和中序遍历求后继都有这样的对称关系。因此,总结出共性的东西,许多题目就可以迎刃而解了。问一问读到这里
的读者,你现在能够自己在脑子里面,非常轻松地像上面那样,把这个例子里面的情况都条理清楚地分析总结出来吗?如果现在还不行,到考试之前,你必须掌握到这种程度,才
能得到一个自己很满意的分数。
经过以上的三个过程复习,相信读者对数据结构的掌握就可以到达比较高的水平了,如果参加考试,获得一个比较满意的成绩也很有希望了。当然,达到这一
步并不容易,大量的练习是真正掌握的必由之路。因此,我们建议大家能够下功夫把本书中的题目完整地做一遍。能够真正把本书中的所有题都掌握,绝不仅仅意味着仅会了书中这几百道题目,而是意味着对数据结构这门课程的理解,以及对问题的分析能力都有很大
的提高,这样在考场上即使遇到未曾见过的题目,也就可以从容应对了
数据结构的复习
第一章 数据结构基本概念
1、基本概念:理解什么是数据、数据对象、数据元素、数据结构、数据的逻辑结构与物理结构、逻辑结构与物理结构间的关系。
2、面向对象概念:理解什么是数据类型、抽象数据类型、数据抽象和信息隐蔽原则。了解什么是面向对象。由于目前关于这个问题有许多说法,我们采用了一种最流行的说法,即Coad与Yourdon 给出的定义:面向对象 = 对象 + 类 + 继承 + 通信。
要点:
·抽象数据类型的封装性
·面向对象系统结构的稳定性
·面向对象方法着眼点在于应用问题所涉及的对象
3、数据结构的抽象层次:理解用对象类表示的各种数据结构
4、算法与算法分析:理解算法的定义、算法的特性、算法的时间代价、算法的空间代价。
要点:·算法与程序的不同之处需要从算法的特性来解释
·算法的正确性是最主要的要求
·算法的可读性是必须考虑的
·程序的程序步数的计算与算法的事前估计
·程序的时间代价是指算法的渐进时间复杂性度量
第二章 数组
1、作为抽象数据类型的数组:数组的定义、数组的按行顺序存储与按列顺序存储
要点:
·数组元素的存放地址计算
2、顺序表:顺序表的定义、搜索、插入与删除
要点:
·顺序表搜索算法、平均比较次数的计算
·插入与删除算法、平均移动次数的计算
3、多项式:多项式的定义
4、字符串:字符串的定义及其操作的实现
要点:
·串重载操作的定义与实现
第三章 链接表
1、单链表:单链表定义、相应操作的实现、单链表的游标类。
要点:
·单链表的两种定义方式(复合方式与嵌套方式)
·单链表的搜索算法与插入、删除算法
·单链表的递归与迭代算法
2、循环链表:单链表与循环链表的异同
3、双向链表:双向链表的搜索、插入与删除算法、链表带表头结点的优点
4、多项式的链接表示
第四章 栈与队列
1、栈:栈的特性、栈的基本运算
要点:
·栈的数组实现、栈的链表实现
·栈满及栈空条件、抽象数据类型中的先决条件与后置条件
2、栈的应用:用后缀表示计算表达式,中缀表示改后缀表示
3、队列:队列的特性、队列的基本运算
要点:
·队列的数组实现:循环队列中队头与队尾指针的表示,队满及队空条件
·队列的链表实现:链式队列中的队头与队尾指针的表示、
4、双向队列:双向队列的插入与删除算法
5、优先级队列:优先级队列的插入与删除算法
第五章 递归与广义表
1、递归:递归的定义、递归的数据结构、递归问题用递归过程求解
要点:·链表是递归的数据结构,可用递归过程求解有关链表的问题
2、递归实现时栈的应用
要点:·递归的分层(树形)表示:递归树
·递归深度(递归树的深度)与递归工作栈的关系
·单向递归与尾递归的迭代实现
3、广义表:广义表定义、广义表长度、广义表深度、广义表表头、广义表表尾
要点:
·用图形表示广义表的存储结构
·广义表的递归算法
第六章 树与森林
1、树:树的定义、树的基本运算
要点:
·树的分层定义是递归的
·树中结点个数与高度的关系
2、二叉树:二叉树定义、二叉树的基本运算
要点:
·二叉树性质、二叉树中结点个数与高度的关系、不同种类的二叉树棵数
·完全二叉树的顺序存储、完全二叉树的双亲、子女和兄弟的位置
·二叉树的前序·中序·后序·层次遍历
·前序
·中序
·后序的线索化二叉树、前驱与后继的查找方法
3、霍夫曼树:霍夫曼树的构造方法、霍夫曼编码、带权路径长度的计算
4、树的存储:树的广义表表示、树的双亲表示、树与二叉树的对应关系、树的先根·中根·后根·层次遍历。
5、堆:堆的定义、堆的插入与删除算法
要点:
·形成堆时用到的向下调整算法及形成堆时比较次数的上界估计
·堆插入时用到的向上调整算法
第七章 集合与搜索
1、集合的概念:集合的基本运算、集合的存储表示
要点:
·用位数组表示集合时集合基本运算的实现
·用有序链表表示集合时集合基本运算的实现
2、并查集:并查集定义、并查集的三种基本运算的实现
3、基本搜索方法
要点:
·对一般表的顺序搜索算法(包括有监视哨和没有监视哨)
·对有序顺序表的顺序搜索算法、用判定树(即扩充二叉搜索树)描述搜索,以及平均搜索长度(成功与不成功)的计算。
·对有序顺序表的折半搜索算法、用判定树(即扩充二叉搜索树)描述搜索,以及平均搜索长度(成功与不成功)的计算。
4、二叉搜索树:
要点:
·动态搜索树与静态搜索树的特性
·二叉搜索树的定义、二叉搜索树上的搜索算法、二叉搜索树搜索时的平均搜索长度(成功与不成功)的计算。
·AVL树结点上的平衡因子、AVL树的平衡旋转方法
·高度为h的AVL树上的最少结点个数与最多结点个数
· AVL树的搜索方法、插入与删除方法
第八章 图
1、图:图的定义与图的存储表示
要点:
·邻接矩阵表示(通常是稀疏矩阵)
·邻接表与逆邻接表表示
·邻接多重表(十字链表)表示
2、深度优先遍历与广度优先遍历
要点:
·生成树与生成树林的定义
·深度优先搜索是个递归的过程,而广度优先搜索是个非递归的过程
·为防止重复访问已经访问过的顶点,需要设置一个访问标志数组visited
3、图的连通性
要点:
·深度优先搜索可以遍历一个连通分量上的所有顶点
·对非连通图进行遍历,可以建立一个生成森林
·对强连通图进行遍历,可能建立一个生成森林
·关节点的计算和以最少的边构成重连通图
4、最小生成树
要点:
·对于连通网络、可用不会构成环路的权值最小的n-1条边构成最小生成树
·会画出用Kruskal算法及Prim算法构造最小生成树的过程
5、单源最短路径
要点:
·采用逐步求解的方式求某一顶点到其他顶点的最短路径
·要求每条边的权值必须大于零
6、活动网络
要点:
·拓扑排序、关键路径、关键活动、AOE网
·拓扑排序将一个偏序图转化为一个全序图。
·为实现拓扑排序,要建立一个栈,将所有入度为零的顶点进栈
·关键路径的计算
首先,是一个学“活”的过程,就要要求我们对书中的每一个算法,能够在脑海中建立起相应的模型,而不是死板的算法。比如树的遍历非递归算法,在入栈与出栈的过程
中,我们就要在脑海中形成访问树每个结点的过程,真正掌握住这个算法。这样,全书复习下来,你的脑海中就有了整个数据结构的模型概念,对任何一个陌生的算法,将不感到
生疏和害怕。
有些同学到了此处就觉得数据结构已经学好,可以万事大吉了,其实这还远远不够,如果参加考试,往往会拿不到高分,甚至还会纳闷,为何自己数据结构学的这样好,成
绩却不尽如人意,因此产生了批卷老师判错的想法。所以第二个过程,就是一个学“死”的过程,这个过程要求,要记住书中的算法(功利一点就是要背诵会所报考学校的考试要
求的算法)。有的学校有别的特殊要求,也一并背会。如上海交通大学喜欢考平均复杂度的分析这样的题目,我们在书上可以找到这样的分析一共十一个,全部背会,就免去了在
考场上分析的麻烦,如果连答案都能记住,那么,也不会因为粗心失分了。这一过程也许有些枯燥,但却是最重要的过程,比如说背会了树的后序遍历非递归,遇到了像求某个结
点的所有祖先,两个结点的共同祖先这样的题,不用想,直接套用。这样才是考试的高分的关键:在考场上,遇到考题,不用思考,直接从脑海中找匹配的算法,直接引用。有了第二个过程的辛苦,我们就可以得到一个比较高的分数了,如果还想提高,就
要进行第三个过程,再学“活”的过程。这一个过程中就要要求我们,在第二步的基础上,多进行思考,看看有哪些算法有共性,比如说:树的前序非递归遍历算法和图的深度优
先遍历算法是不是类似啊,有些什么不同,有些什么相同,为什么会相同;森林转化为二叉树和图的生成树的算法也是这样,等等。总结出这种共性,这样就能正确有效的记忆算
法,同时,遇到难题不至于慌乱,能够从容下手解题。
对于总结共性问题上,这里举一小个例子,(呵呵,我当初总结出这个,并且和kaoyan.com斑竹一具讨论确定后三天,就在2002年交大第一题考出类似东东)比如树的遍
历,不管是递归还是非递归,也不管是线索树,还是头结点有父母信息的树,它的遍历其实就是一个寻找到遍历的第一个结点,然后再寻找它的后继结点的过程,我们归纳到此处,就可以试着总结一下三种
遍历的后继结点是哪个,有几种情况:
对于前序遍历,它的后继如下:
(1)若有左孩子,则后继是左孩子;
(2)若无左孩子,有右孩子,则后继是右孩子;
(3)若既无左孩子,又无右孩子,则是一片叶子;再讨论:
(a)若是其父母的左孩子,且父母有右孩子,则后继是父母的右孩子。
(b)若是其父母的左孩子,且父母无右孩子;
(c)若是其父母的右孩子。
b,c都表示这是某个节点的左子树前序遍历的最后一个节点,则需要找第一个有右子树的“左祖先”(定义“左祖先”,即找第一个使得当前节点在这个祖先的左子树上),
然后后继就是这个祖先的右孩子。
对于中序遍历,它的后继如下:
(1)如有右孩子,后继是右孩子的最左下节点;
(2)若无右孩子,且是父母的左孩子,则后继就是父母;
(3)若无右孩子,且是父母的右孩子,则一直上溯到第一个“左祖先”(定义如前)则后继就是这个祖先。若无这样的祖先,说明已经遍历完毕。
对于后序遍历,它的后继如下:
(1)若是父母的右孩子,则后继是父母;
(2)若是父母的左孩子,且父母无右子树,则后继是父母;
(3)若是父母的左孩子,父母有右子树,则后继是父母右子树的最先访问到的节点(指向父母的右子树后,一直往左,若不行的话,往右一步,一直到叶子)
总结完了,想一想,我们还能得到哪些提示?经常有一类型题目,要求求某个结点的直接前驱。其实求前序遍历的前驱和求后序遍历的后继是一样的,只不过把左换成右而
已,前序遍历的求后继和后序遍历的求前驱、中序遍历的求前驱和中序遍历求后继都有这样的对称关系。因此,总结出共性的东西,许多题目就可以迎刃而解了。问一问读到这里
的读者,你现在能够自己在脑子里面,非常轻松地像上面那样,把这个例子里面的情况都条理清楚地分析总结出来吗?如果现在还不行,到考试之前,你必须掌握到这种程度,才
能得到一个自己很满意的分数。
经过以上的三个过程复习,相信读者对数据结构的掌握就可以到达比较高的水平了,如果参加考试,获得一个比较满意的成绩也很有希望了。当然,达到这一
步并不容易,大量的练习是真正掌握的必由之路。因此,我们建议大家能够下功夫把本书中的题目完整地做一遍。能够真正把本书中的所有题都掌握,绝不仅仅意味着仅会了书中这几百道题目,而是意味着对数据结构这门课程的理解,以及对问题的分析能力都有很大
的提高,这样在考场上即使遇到未曾见过的题目,也就可以从容应对了
数据结构的复习
第一章 数据结构基本概念
1、基本概念:理解什么是数据、数据对象、数据元素、数据结构、数据的逻辑结构与物理结构、逻辑结构与物理结构间的关系。
2、面向对象概念:理解什么是数据类型、抽象数据类型、数据抽象和信息隐蔽原则。了解什么是面向对象。由于目前关于这个问题有许多说法,我们采用了一种最流行的说法,即Coad与Yourdon 给出的定义:面向对象 = 对象 + 类 + 继承 + 通信。
要点:
·抽象数据类型的封装性
·面向对象系统结构的稳定性
·面向对象方法着眼点在于应用问题所涉及的对象
3、数据结构的抽象层次:理解用对象类表示的各种数据结构
4、算法与算法分析:理解算法的定义、算法的特性、算法的时间代价、算法的空间代价。
要点:·算法与程序的不同之处需要从算法的特性来解释
·算法的正确性是最主要的要求
·算法的可读性是必须考虑的
·程序的程序步数的计算与算法的事前估计
·程序的时间代价是指算法的渐进时间复杂性度量
第二章 数组
1、作为抽象数据类型的数组:数组的定义、数组的按行顺序存储与按列顺序存储
要点:
·数组元素的存放地址计算
2、顺序表:顺序表的定义、搜索、插入与删除
要点:
·顺序表搜索算法、平均比较次数的计算
·插入与删除算法、平均移动次数的计算
3、多项式:多项式的定义
4、字符串:字符串的定义及其操作的实现
要点:
·串重载操作的定义与实现
第三章 链接表
1、单链表:单链表定义、相应操作的实现、单链表的游标类。
要点:
·单链表的两种定义方式(复合方式与嵌套方式)
·单链表的搜索算法与插入、删除算法
·单链表的递归与迭代算法
2、循环链表:单链表与循环链表的异同
3、双向链表:双向链表的搜索、插入与删除算法、链表带表头结点的优点
4、多项式的链接表示
第四章 栈与队列
1、栈:栈的特性、栈的基本运算
要点:
·栈的数组实现、栈的链表实现
·栈满及栈空条件、抽象数据类型中的先决条件与后置条件
2、栈的应用:用后缀表示计算表达式,中缀表示改后缀表示
3、队列:队列的特性、队列的基本运算
要点:
·队列的数组实现:循环队列中队头与队尾指针的表示,队满及队空条件
·队列的链表实现:链式队列中的队头与队尾指针的表示、
4、双向队列:双向队列的插入与删除算法
5、优先级队列:优先级队列的插入与删除算法
第五章 递归与广义表
1、递归:递归的定义、递归的数据结构、递归问题用递归过程求解
要点:·链表是递归的数据结构,可用递归过程求解有关链表的问题
2、递归实现时栈的应用
要点:·递归的分层(树形)表示:递归树
·递归深度(递归树的深度)与递归工作栈的关系
·单向递归与尾递归的迭代实现
3、广义表:广义表定义、广义表长度、广义表深度、广义表表头、广义表表尾
要点:
·用图形表示广义表的存储结构
·广义表的递归算法
第六章 树与森林
1、树:树的定义、树的基本运算
要点:
·树的分层定义是递归的
·树中结点个数与高度的关系
2、二叉树:二叉树定义、二叉树的基本运算
要点:
·二叉树性质、二叉树中结点个数与高度的关系、不同种类的二叉树棵数
·完全二叉树的顺序存储、完全二叉树的双亲、子女和兄弟的位置
·二叉树的前序·中序·后序·层次遍历
·前序
·中序
·后序的线索化二叉树、前驱与后继的查找方法
3、霍夫曼树:霍夫曼树的构造方法、霍夫曼编码、带权路径长度的计算
4、树的存储:树的广义表表示、树的双亲表示、树与二叉树的对应关系、树的先根·中根·后根·层次遍历。
5、堆:堆的定义、堆的插入与删除算法
要点:
·形成堆时用到的向下调整算法及形成堆时比较次数的上界估计
·堆插入时用到的向上调整算法
第七章 集合与搜索
1、集合的概念:集合的基本运算、集合的存储表示
要点:
·用位数组表示集合时集合基本运算的实现
·用有序链表表示集合时集合基本运算的实现
2、并查集:并查集定义、并查集的三种基本运算的实现
3、基本搜索方法
要点:
·对一般表的顺序搜索算法(包括有监视哨和没有监视哨)
·对有序顺序表的顺序搜索算法、用判定树(即扩充二叉搜索树)描述搜索,以及平均搜索长度(成功与不成功)的计算。
·对有序顺序表的折半搜索算法、用判定树(即扩充二叉搜索树)描述搜索,以及平均搜索长度(成功与不成功)的计算。
4、二叉搜索树:
要点:
·动态搜索树与静态搜索树的特性
·二叉搜索树的定义、二叉搜索树上的搜索算法、二叉搜索树搜索时的平均搜索长度(成功与不成功)的计算。
·AVL树结点上的平衡因子、AVL树的平衡旋转方法
·高度为h的AVL树上的最少结点个数与最多结点个数
· AVL树的搜索方法、插入与删除方法
第八章 图
1、图:图的定义与图的存储表示
要点:
·邻接矩阵表示(通常是稀疏矩阵)
·邻接表与逆邻接表表示
·邻接多重表(十字链表)表示
2、深度优先遍历与广度优先遍历
要点:
·生成树与生成树林的定义
·深度优先搜索是个递归的过程,而广度优先搜索是个非递归的过程
·为防止重复访问已经访问过的顶点,需要设置一个访问标志数组visited
3、图的连通性
要点:
·深度优先搜索可以遍历一个连通分量上的所有顶点
·对非连通图进行遍历,可以建立一个生成森林
·对强连通图进行遍历,可能建立一个生成森林
·关节点的计算和以最少的边构成重连通图
4、最小生成树
要点:
·对于连通网络、可用不会构成环路的权值最小的n-1条边构成最小生成树
·会画出用Kruskal算法及Prim算法构造最小生成树的过程
5、单源最短路径
要点:
·采用逐步求解的方式求某一顶点到其他顶点的最短路径
·要求每条边的权值必须大于零
6、活动网络
要点:
·拓扑排序、关键路径、关键活动、AOE网
·拓扑排序将一个偏序图转化为一个全序图。
·为实现拓扑排序,要建立一个栈,将所有入度为零的顶点进栈
·关键路径的计算