导读
本书是关于数据结构与算法的经典教材,主要论述了数据的逻辑结构、存储结构、算法设计以及算法评价,使读者能够深入了解线性表、栈、队列、树、图等数据结构以及排序和检索等基础算法,并掌握在不同的数据结构上进行有关算法设计的思想和技巧。书中包含大量代码实例和详尽的解释,非常适合作为计算机专业本科生的低年级入门教材。
全书由浅入深,分成了五部分。针对计算机专业的低年级本科生而言,可重点学习前面三部分的内容,学有余力的读者可以在此基础上继续研读后面的内容。下面为读者介绍本书的重点内容。
基础知识
本书第1章介绍数据结构的入门基础知识。其中1.1节主要介绍数据结构的定义、基本术语以及数据结构的基本类型。读者可通过该节的学习,重点理解数据结构对抽象表达、程序建模的重要作用,了解在实际应用过程中数据结构的优缺点分析方法。1.2节重点介绍基于抽象数据类型的数据结构描述方法,这是整本书中各个数据结构的基本描述方法。读者可穿插翻阅后面第4章至第6章中各种数据结构的抽象数据类型,加深对此概念的理解。此外,通过学习1.4节,读者可进一步理解数据结构、问题与算法的关系。
第2章介绍本课程涉及的一些基础数学知识。这里介绍的绝大部分数学知识,读者都在中学阶段学过。读者可简单快速地浏览一下,用时再来回顾翻查。
第3章主要介绍算法复杂度的定义以及分析方法。通过学习这一章,读者就能了解渐近算法复杂度分析方法,理解上界分析、下界分析以及确切界的具体定义和快速分析方法,并掌握针对任意给定程序片段的基本分析方法。
数据结构
本书第II部分是整本教材的重点,主要讨论了线性表(List)、二叉树(Binary Tree)、普通树(General Tree)和图(Graph)的定义与实现方法。为了能对各类数据结构融会贯通,建议读者将第4章至第6章以及第11章放在一起来进行对比学习。
第4章主要介绍线性表的定义、存储实现方法,以及插入、删除和定位等基本运算;介绍了栈和队列的基本定义、基本操作,以及灵活运用线性表解决现实工程问题的方法。本章的重点是分析线性表的数组和链表这两种实现方法的优缺点,实现线性表的插入、删除和定位等基本运算的算法,掌握栈的入栈和出栈的操作以及队列的入队和出队的操作。本章的难点是掌握单链表及循环链表的算法设计综合应用,掌握在循环队列上进行入队、出队以及求队列长度的操作。
第5章主要阐述二叉树的基本定义和存储实现方式,介绍二叉树的遍历和搜索等基本操作,并讨论堆和哈夫曼树的基本原理和实现方法。本章的重点是基于链接和数组两种存储结构的二叉树实现方法,基于递归的二叉树遍历算法,以及二叉检索树的搜索、删除结点和添加结点等操作的实现。本章的难点是堆的构建,插入删除结点的算法实现,以及哈夫曼树和哈夫曼编码的原理。
第6章主要介绍普通树的基本定义、遍历算法,以及树的基本存储结构的原理。本章的重点是左子结点/右兄弟结点的实现方法,以及普通树和森林与二叉树的相互转换方法。本章的难点是普通树的顺序存储方法。
第11章主要介绍图的定义和实现方法,图的遍历算法、拓扑排序算法、最短路径算法以及最小生成树算法。本章的重点是图的邻接表和邻接矩阵两种实现方法的原理以及优缺点对比,基于递归函数的图的遍历算法的实现,拓扑排序算法的实现方法以及应用。本章的难点是Dijkstra最短路径算法、Floyd最短路径算法,以及最小支撑树算法。
排序与检索算法
第III部分主要介绍排序与检索这两类比较常见的算法,读者在掌握了前面所学数据结构的基础上,可以较为容易地掌握这些算法。
第7章和第8章主要介绍排序算法的定义、排序算法的稳定性分析方法、排序算法的设计与实现、排序算法的复杂度对比分析,以及排序算法的应用。这两章的重点是快速排序算法、归并排序算法以及堆排序算法的实现。这两章的难点是希尔排序算法的原理和实现,以及快速排序算法的改进方法。
第9章主要介绍检索的基本原理和二分法检索,讨论了哈希表的原理、构建以及相关操作。本章的重点是哈希表的原理、哈希函数的设计方法,以及哈希表的插入和删除算法的实现。本章的难点是哈希表的冲突解决策略。
第10章主要介绍线性索引、2-3树索引、B/B+树索引的构建方法,以及算法复杂度分析方法。本章的重点是线性索引和2-3树索引的插入、删除和检索算法,以及B树和B+树的定义。本章的难点是B树和B+树的插入、删除和检索算法。
至此,通过前三部分的学习,读者已掌握了数据结构的基本知识、理论和分析方法,为从事相关计算机程序分析和设计工作以及相关专业的后续课程学习打下了扎实的基础。读者在本书各章节的学习过程中,可动手实践对应的程序代码,掌握各类数据结构与算法的实现方法。华南理工大学计算机科学与工程学院的“数据结构”课程采用了本书作为教材。我们授课团队结合本书设计了相应的在线教学视频(https://next.xuetangx.com/course/SCUT08091000960/),感兴趣的读者可参考学习,定能起到事半功倍的作用。采用本书作为教材的授课教师,也可登录华信教育资源网(www.hxedu.com.cn)注册后免费下载我们的教学用PPT等相关资料。
吕建明教授 博导
华南理工大学计算机科学与工程学院
Preface
We study data structures so that we can learn to write more efficient programs. But why must programs be efficient when new computers are faster every year? The reason is that our ambitions grow with our capabilities. Instead of rendering efficiency needs obsolete, the modern revolution in computing power and storage capability merely raises the efficiency stakes as we attempt more complex tasks.
The quest for program efficiency need not and should not conflict with sound design and clear coding. Creating efficient programs has little to do with “programming tricks” but rather is based on good organization of information and good algorithms. A programmer who has not mastered the basic principles of clear design is not likely to write efficient programs. Conversely, concerns related to development costs and maintainability should not be used as an excuse to justify inefficient performance. Generality in design can and should be achieved without sacrificing performance, but this can only be done if the designer understands how to measure performance and does so as an integral part of the design and implementation process. Most computer science curricula recognize that good programming skills begin with a strong emphasis on fundamental software engineering principles. Then, once a programmer has learned the principles of clear program design and implementation, the next step is to study the effects of data organization and algorithms on program efficiency.
Approach: This book describes many techniques for representing data. These techniques are presented within the context of the following principles:
1. Each data structure and each algorithm has costs and benefits. Practitioners need a thorough understanding of how to assess costs and benefits to be able to adapt to new design challenges. This requires an understanding of the principles of algorithm analysis, and also an appreciation f