第1章 算法基础知识
在开始算法学习之前,你需要一点背景知识。简单地说,首先需要知道的是算法是完成某些事情的方法。它定义了用某个方法执行一个任务的步骤。
这个定义看起来足够简单,但是没有人为了做一件十分简单的工作而写算法。没有人写指令来获取数组中的第四个元素。这只是假设这是一个数组定义的一部分,并且你知道怎么去做(如果你知道如何在这个问题中使用编程语言)。
一般来说,人们只是为了完成复杂的任务而写算法。算法解释了如何找到一个复杂代数问题的答案,如何在一个包含数千条街道的网络中找到最短路径,抑或是如何在数百个投资中找到最好的投资组合来使利益最大化。
本章介绍一些基本的算法概念。如果想从算法学习中获得最大的收获,就应该理解它们。
跳过这一章然后去学某个特定的算法似乎很有诱惑力,但是你至少应该浏览一下这一章。请着重注意1.4.1节,因为对运行时间是否有良好理解意味着算法能否在数秒、数小时内完成任务,还是永远不能完成任务。
1.1 方法
为了尽可能地了解一个算法,你需要做出更多努力而非简单地遵循它的步骤。你需要理解以下内容:
算法的行为: 它寻找出了最好的方法还是仅仅找出了一个可行的解决办法?可能有多个最佳的解决方案吗?是否有一个方法可以从其他解决方案中寻找到一个“最佳”解决方案?
算法的速度:这个算法是快还是慢?还是它通常是快的,但有时对于某些输入慢?
算法的存储要求:这个算法需要多大的存储空间?这个大小合理吗?这个算法是否需要数十亿TB的存储空间,比一台计算机可能有的存储空间还多(至少对现在的计算机来说如此)?
算法设计主要使用的技巧:是否可以利用这些技术解决类似的问题?
这本书涵盖了所有这些主题。然而,本书没有试图用数学的精确理论去涵盖每一个算法的每一个细节。本书使用一种直观的方法来解释算法及其性能,但是本书没有用严谨的细节去分析算法的性能。尽管这种细节分析的证明可能是有趣的,但它也可能让人混乱,并且会占用大量的篇幅,提供了对大多数程序员来说不必要的细节。毕竟,这本书主要适用于需要完成工作的专业程序员。
本书把具有相关主题的算法归在一章。有时这个主题是它们所执行的任务(排序、搜索、网络算法),有时是它们所使用的数据结构(链表、数组、散列表、树),有时是它们使用的技巧(递归、决策树、分布式算法)。粗看起来,这些分组似乎是任意的,但当你读到这些算法的时候,可以看到它们很好地组合在一起。
除了这些类别,许多算法的基本主题跨越章节界限。例如,树算法(第10、11和12章)往往是高度递归的(第9章)。链表(第3章)可用于建立数组(第4章)、散列表(第8章)、栈(第5章)和队列(第5章)。引用和指针的概念可以用来建立链表(第3章)、树(第10、11和12章)和网络(第13和14章)。在阅读时,请关注这些共同的线索。附录A中总结了常见的策略,这些策略能使这些想法更容易被理解。