前 言 一个木匠学徒可能仅仅希望能够熟练使用铇子和锯,但是一个工匠能手需要会使用各种复杂的工具。计算机编程同样需要一些复杂的工具来应对现实世界中纷繁复杂的应用,而且只有通过实际使用这些工具,才能掌握它们的使用技术。本书主要介绍了数据结构问题的解决方法、数据抽象、软件工程的一些规则以及程序设计中作为基本工具的算法比较分析。本书详细介绍了几个具有实际规模的案例分析,演示了如何应用这些工具构建完整的计算机程序。 我们所研究的许多算法和数据结构都具有内在的简洁性,这种简洁性掩盖了它们应用的范围和权限。不久以后,学生们将发现,通常对用在入门课程中的简单方法可以进行很多改进。但方法的简洁性可能趋向于不确定性。学生们将会发现在特定的应用中,具体哪一种方法是最好的,并不是特别清楚。因此这为我们提供了介绍真正难题的机会,这些问题具有内在的意义和实际的重要性,并且还为我们提供了展示关于算法验证和分析的数学方法的应用。 许多学生发现将抽象思想转换为实际应用非常困难。因此,本书特别介绍了由思想构建具体算法的方法和将算法细化为能够应用于实际问题的具体程序的过程。类似的,在选择数据结构和它们的实现之前,首先要进行数据的说明和抽象这一过程。 我们认为,从具体到抽象是一个提升过程,在开发具有启发性的示例后,紧接着要以更通用的方式陈述其中的思想。在大多数学生学习的早期阶段,需要强化他们直接应用所研究的思想的能力,并且他们需要实际练习编写和运行程序,演示他们所学的每一个重要概念。因此本书中介绍了许多例程,包括一些短小的函数和一些完整程序。另外,练习和编程项目是本书不或缺的一部分。其中许多是所研究主题的直接应用,常常需要编写并运行程序,因此可以测试并比较一些算法。某些项目较大,并且少数项目适合于一小组学生共同完成。 通过开发第一个大型项目(CONWAY的Life游戏),第1章详细说明了自顶向下的细化原则、程序设计和测试等内容,并论述了要求学生们遵守的一些规则。同时,这个项目为学生提供了回顾C语言语法的机会,其中C语言是本书使用的主要编程语言。 第2章介绍了软件工程的基本概念,包括问题说明和分析、原型、数据抽象、算法设计、细化、验证和分析。这一章中应用这些规则来开发Life游戏的第二个程序。该程序基于一个十分巧妙的算法,演示了需要精确地说明和验证的原因,以及在选择数据结构时需要特别注意的原因。 第3章继续阐述了数据抽象和算法设计,主要研究了一种抽象数据类型“堆栈”和作为问题求解方法的“递归”,并研究了堆栈、递归和某些树的紧密关系。 队列和列表是第4章和第5章中的中心主题。这两章揭示了每种抽象数据类型的几种不同的实现方式,开发了大量的应用程序,演示了不同实现的相对优点,并非正式地介绍了算法分析。这两章的主要目标是使得学生接受数据抽象和应用自顶向下的设计方法来设计数据和算法。 第6、7、8章介绍了搜索、排序和表访问(包括散列)的算法。这些章节举例说明了算法和相关抽象数据类型、数据结构及其实现的相互作用。书中介绍了用于基本算法分析的Big-O表示法,并强调了考虑最佳利用空间、时间和编程量时所制定的重要选择。 这些选择要求我们找出评价算法的分析方法,并且找出这样的分析方法是一场战争,对于这场战争来说,组合数学提供了兵工厂。对于初级水平的学生,我们不能期望他们具有很好的武装,也不能期望他们具有能够使他们的技能趋于完美的完备数学知识。因此,我们的目标是帮助学生们认识这种技能的重要性。 二叉树是最完美、最有用的数据结构之一。第9章中研究了二叉树,并结合了列表、搜索和排序概念的介绍。作为采用递归方法定义的数据结构,二叉树为学生提供了一个很好的熟悉递归的机会,使他们能够适应将递归应用于数据结构和算法的方法。本章从基本主题开始介绍,然后逐步介绍分裂树(splay tree)和平推算法分析(amortized algorithm analysis)等高级主题。 第10章继续研究了一些更复杂的数据结构,包括trie、B-树和红黑树。第11章中介绍了图。图是一种更常见的数据结构,在问题求解中非常有用。 第12章中的案例分析相当详细地验证了波兰表示法,并探究了递归、树和堆栈在问题求解和算法开发时的相互关系。某些问题的解决方法可以作为编译器设计的非正式介绍。通常在一个功能齐备的C语言程序中开发算法。这个程序按照普通(中缀)形式接收一个表达式作为输入,并将表达式转换为后缀式,然后对于特定的变量值求解表达式的值。 附录中讨论了一些主题,严格地说,这些主题并不是本书主题的适当部分,但某些学生常常不具备这些预备知识。 附录A给出了离散数学的几个主题。它的最后两节介绍了斐波纳契数列和加泰罗尼亚数字,这些都是高级知识,本书正文中并不需要它们,但包含它们是为了鼓励学生对数学更加感兴趣。 递归的消除是大多数程序员不需要学习的主题。但在目前,某些重要的工作还必须使用不支持递归的高级语言(例如FORTRAN或COBOL)来完成。因此有时候还需要一些手工的递归消除方法,这些方法被收集在附录B中。某些教师希望在第9章中包含线索二叉树的内容;因此这一部分的内容在附录B中提供,它独立于附录B中其他的内容。 最后,附录C简短地介绍了C语言知识。虽然它不是对C语言的全面介绍,但将其用作C语法知识的一个回顾,对学生来说还是具有参考价值的。 第二版中的变化 在这一版中,整个正文都被仔细地审阅和修订了,反映了许多读者的思想,这些读者提供了他们学习本书的心得。主要的改动之处总结如下: ● 重新编写、修订和推敲了所有的程序,以强调数据抽象、开发和使用可重用代码,并加强了风格的标准化和简洁性。 ● 通过在子程序中包含非正式说明(precondition和postcondition),强调了程序的说明文档。 ● 文中更早地介绍了递归,然后在后边通过重用递归,进行强调。 ● 涵盖了更高级、更现代的主题,这些主题被包含在几个新的章节中,主要包括分裂树、红黑树和分期清偿算法分析。 ● 文中着重介绍了新的案例分析,如第5章中的最小化文本编辑器。 ● 添加了新的练习和编程项目,包括关于信息检索的项目,该项目要求学生比较几种不同的数据结构和算法的性能。 ● 有关图论的材料和图的算法内容被放置到一个独立的章中。 ● 简化了列表的描述。 ● 书中给出的所有程序和程序摘要的源码都可以通过互联网获得。在使用ftp下载这些软件时软件位于目录。 ● 进授本书的教师可以免费获得Instructor s Resoure Manual,您可以填写本书后所附的教辅资料申请及教师信息反馈表索取该教辅。 课程结构 学习本书的先决条件是要具备编程方面的预备知识,并要求备有使用C语言基本功能的经验。附录C提供了C语言的一些高级内容,这些高级内容在入门课程中常常被省略。有关高等数学方面的优秀知识几乎满足所有的算法分析,但有关离散数学方面的预备知识也被证明是非常有价值的。附录A回顾了所需要的所有数学知识。 本书可用作一些课程的教材,例如ACM 课程CS2(程序设计和实现),ACM课程CS7(数据结构和算法分析),或组合这些内容的课程。本书覆盖了ACM/IEEE关于数据结构和算法方面的知识单元(详见下面的“注释”部分)的大部分内容。主要包括: AL1 基本数据结构,例如数组、表、堆栈、队列、树和图; AL2 抽象数据类型; AL3 递归和递归算法; AL4 使用Big_ O表示法的复杂分析; AL6 排序和搜索; AL8 关于大型案例分析的实际问题求解策略。 注释: 参考1991年的Computing Curricula:Report of the ACM/IEEE-CS Joint Curriculum Task Force,ACM Press,New York,1990。 本书并未涉及三个最高级的知识单元,AL5(复杂类,NP完全问题),AL7(可计算性和不可判定性)以及AL9(并行和分布式算法)。 本书大多数章节的结构安排十分合理,首先提供了核心主题,接着是具体的示例、应用和大型案例分析。因此,如果时间有限,仅可简短地学习一个主题,为了不失连续性,可以快速地阅读每一章的核心主题。但当时间允许时,学生和教师都应当阅读附录的主题,并完成所有的练习项目。 一个两学期课程可以完全覆盖本书,从而获得许多主题的一个满意集成,包括问题求解、数据结构、程序开发和算法分析等领域。学生们需要时间和练习,才能理解通用的方法。通过学习组合数据抽象、数据结构、算法和它们在实际项目中的实现,可以建立一个坚实的基础,在此基础之上,可以学习具有更多理论性的课程。 即使本书并未覆盖它的全部内容,但也提供了足够的深度,引导学生在以后的学习中,继续将本书作为一本参考资料。在任何情况下,给出一些主要的编程项目,并有充足的时间完成它们,都是非常重要的。 致谢 多年以来,本书和它的先驱Pascal语言版本的Data Structures and Program Design已经受益于许多人的大量贡献:家庭、朋友、同事和学生。第一版中列举了一些人,他们的贡献特别显著。自从第一版出版后,就被翻译为多种语言版本,并且许多人友善地提出了大量的评论和建议。特别要感谢的是一些评论家对本书提出了宝贵的建议,他们是:ALEX RYBA(Marquette 大学)、RICHARD SAUNDERS(Arizona大学)、DAVID STRAIGHT(Tennessee,Knoxville大学)、CARLOS CUNHA(Boston 大学)和GREG CAMERON(Ricks 大学)。 本书也感谢如下一些人的帮助:GEORGE EDMUNDS、TOM HORTON、 SAM HSU、MARIA PETRIE(Florida Atlantic 大学)、ROLIE GUILD(Nova 东南大学)、LOUIS VOSLOO(Y&Y,Inc.)、NELSON FELIPPE DA SILVA(Polydata,Inc.)、LUIZ BIAVATTI、A.CARLOS TONDO(T&T TechWorks,Inc.)、ED HAUGHNEY、ANDREW NATHANSON、RED VISCUSO和CAREN E.TONDO。 Prentice Hall的编辑员工,特别是发行人ALAN APT和管理编辑LAURA STEELE,他们为本书付出了极大的努力,使得本书的发行非常成功。 PreTEX公司的JIM COOPER加速了本书的出版,他检测了本书所有的C语言程序,解决了许多问题,并且完成了练习的所有答案,重新编写了程序项目。 最后,请注意本书是根据Robert L.Kruse编写的、基于Pascal语言的Data Structures and Program Design第三版一书,由Clovis L.Tondo和BruceP.Leung改写为基于C的版本而来的。其中Robert L.Kruse主要负责与语言无关的讨论,其他作者负责C语言程序和与语言细节方面的阐述。 ROBERT L.KRUSE CLOVIS L.TONDO BRUCE P.LEUNG