前言

对于正准备阅读本书的读者,我希望你已经有一些编程语言(例如Python)的基础;如果你之前从来没有接触过编程,建议首先学习一门编程语言,然后进行本书的学习!我在本书中使用了Python,因为它对程序员和初学者来说都很容易使用。

算法的目标是解决软件应用程序中经常出现的问题。为大学生讲授算法时,我试图在学生的背景知识和我所讲授的算法概念之间架起一座桥梁。许多教科书虽然编写得非常精美,但在算法解释方面还是太过简单。如果没有一份指南向学生解释如何浏览算法材料,学生们常常无法自学算法。

我将通过一段文字和图P-1来说明本书的目标。我将介绍一些数据结构,并解释如何使用基本的固定长度的数据类型(例如32位的整型或64位的浮点型)对数据进行组织。有些算法,例如二分数组搜索,是直接在数据结构上工作的。更复杂的算法,尤其是图的算法,依赖于一些基本的抽象数据类型。对于抽象数据类型,我会在必要的时候进行介绍,例如堆栈或优先队列。这些数据结构提供了基本操作,可以通过选择正确的数据结构来高效实现。在本书的最后,我将带领读者理解各种不同的算法是如何实现它们的性能的。对于这些算法,我要么用Python展示完整的实现,要么介绍提供了高效实现的第三方Python程序包。

在本书所提供的相关代码资源中,读者将会看到每一章都有一个名为book.py的Python文件,执行这个文件能够生成书中的所有表格。

图P-1 本书技术内容的总结

在本书第1~7章的章末有挑战练习,为读者提供测试自己所学习的新知识的机会。我希望读者在查看我所提供的示例解决方案之前尝试自己完成这些练习。我所提供的解决方案可以在本书配套的代码库中找到。

本书的所有代码都可以在相关联的GitHub代码库http://github.com/heineman/ LearningAlgorithms中找到。这些代码兼容了Python 3.4或更高版本。在相关的时候,我将遵循 Python 的典型做法,使用双下画线方法,例如__str()____len()__。在本书的代码实例中,我使用了两个空格的缩进以减少代码占据页面的宽度,而在代码库中使用了标准的4个空格的缩进。在一些代码清单中,我采用了简洁的单行代码格式,例如if j == lo:break这样的if语句。

本书的代码使用了3个外部的、开放源代码的Python程序库,具体如下。

NumPy 1.19.5。

SciPy 1.6.0。

NetworkX 2.5。

NumPy和SciPy都是极为常见的开源Python程序库,具有极广泛的用户。我使用这两个程序库对算法的运行时间性能进行分析。NetworkX提供了许多适用于图的不同高效算法(详见第7章),它还提供了一种可以直接使用的图数据结构的实现。这些程序库使我不必“事必躬亲”。如果读者没有安装这些程序库,也不会有什么问题,因为我提供了一些应急措施。

本书使用timeit模块所生成的所有计时结果都是通过反复运行代码片段所得的。代码片段常常需要重复运行多次,以保证它所测量的时间是正确的。在运行一定的次数之后,最短的时间(而不是所有运行时间的平均值)被当作运行时间性能。这通常被认为是生成准确计时方案的有效方式,因为多次运行的平均时间在运行受到外部影响(例如操作系统所执行的其他任务)时会影响计时结果。

当一种算法(例如第5章的插入排序)的性能对它的输入高度敏感时,我将会清楚地说明采用所有计时结果的平均时间。

本书的代码库所包含的Python代码超过10,000行,读者可以通过脚本执行本书中的所有测试用例并计算书中的所有表格数据。本书的许多图表可以重新生成。本书的代码按照Python的Docstring约定进行文档说明,代码的覆盖率使用Coverage.py网站检验达到了95%。

如果读者发现技术问题,或者在使用代码示例时遇到问题,可以通过异步社区中的本书页面与我们联系。

本书是为了帮助读者更好地完成工作。一般而言,对于本书所提供的示例代码,读者可以在自己的程序和文档中使用它们,并不需要联系我们以获得许可,除非读者复制了大块的代码。例如,在编写程序时使用了本书的几段代码并不需要许可,但是,销售或发布O’Reilly图书的示例代码需要得到我们的许可;引用本书以及书中的示例代码并不需要获得许可,但是把本书的大量示例代码复制到自己产品的文档中需要获得许可。

我们赞赏注明出处,但一般情况下并不要求。出处注明通常包括书名、作者、出版商和ISBN。例如,《算法学习指南》(Learning Algorithms: A Programmer’s Guide to Writing Better Code),作者George Heineman(O’Reilly)。

如果读者觉得自己对本书的示例代码的使用超出了正常范围或者超出上面的许可,可以通过permissions@oreilly.com与我们联系。

下面是本书所采用的印刷约定。

黑体:表示新的术语及我想要强调的要点。

等宽字体:在程序清单中使用,也用于在段落中表示程序内容,例如变量或函数名、数据类型和关键字。

图标1这种由环尾狐猴所提示的内容是提示或建议。我使用这幅图像的原因是环尾狐猴的联合视野最大可达280°,大于一般的灵长类动物(例如人类)。当出现这个提示图标时,我一般要求读者拓宽自己的视野,去了解一个新的概念或一个新的Python功能。

图标2这种由乌鸦所提示的内容为基本的备注。大量的科研人员发现乌鸦是非常聪明的,是一种能够解决问题的动物,有些乌鸦甚至能够使用工具。我使用这一图标来表示定义新术语或向读者展示一个实用概念,读者在阅读接下来的内容之前应该理解这个术语或实用概念。

蝎子.tif这种由蝎子所提示的内容为警告。我使用蝎子图标来提醒读者在应用算法时必须处理的关键挑战。

图标4

近40年来,O’Reilly Media致力于提供技术和商业培训、知识和卓越见解,来帮助众多公司取得成功。

我们拥有独一无二的专家和革新者组成的庞大网络,他们通过图书、文章、会议和我们的在线学习平台分享知识和经验。O’Reilly的在线学习平台允许你按需访问现场培训课程、深入的学习路径、交互式编程环境,以及O’Reilly和200多家其他出版商提供的大量文本和视频资源。更多相关信息请访问http://oreilly.com。

如果读者对本书有任何的评论或疑问,可以与出版社联系。

美国:

O’Reilly Media, Inc.

1005 Gravenstein Highway North

Sebastopol, CA 95472

中国:

北京市西城区西直门南大街2号成铭大厦C座807室(100035)
奥莱利技术咨询(北京)有限公司

我们为本书提供了一个网页,其中包含勘误表、示例和其他的额外信息,读者可以通过https://oreil.ly/learn-algorithms进行访问。

如果你对本书有什么评论或技术上的建议,请发送电子邮件到 bookquestions@oreilly.com。

关于我们的图片和课程的新闻和信息,可以访问http://oreilly.com。

我认为,算法的研究是计算机科学最精华的部分。感谢读者给我机会展示本书的内容。我还想感谢我的妻子Jennifer,感谢她在本书以及我的另一本著作的编写过程中所给予的支持。感谢我的两个儿子Nicholas和Alexander,他们现在已经长大,已经可以开始学习编程了。

感谢O’Reilly的编辑Melissa Duffield、Sarah Grey、Beth Kelly和Virginia Wilson,感谢他们在组织本书的概念及解释的过程中对我的帮助,他们的帮助有效地提高了本书的质量。感谢本书的技术审稿人员Laura Helliwell、Charlie Lovering、Helen Scott、Stanley Selkow和Aura Velarde,感谢他们减少了书中的不一致之处,提高了算法实现及其解释的质量。如果书中还存在任何缺陷,那肯定都是我自己的责任。