算法基础知识
一些有用的算法
- 数值算法,比如随机化、分解因式、处理质数、数值积分
- 熟练操作常见的数据结构的方法,比如堆、树、平衡树、B数
- 排序和搜索
- 网络算法,比如最短路径、生成树、拓扑排列和流计算
一些常规的问题解决技巧
- 暴力或者穷举搜索
- 分治法
- 回溯法
- 递归
- 分支界限
- 贪心算法和爬山法
- 最小花费算法
- 缩小范围
- 启发式算法
就我个人而言,算法只是一种乐趣,它们就像填字游戏或者数独一样。我喜欢组成一个复杂的算法,倒一些数据进去,然后看到一个美丽的三维图形、一条匹配一系列点的曲线,或者一些其他优雅的答案出现。我喜欢这种感觉。
---------------------罗德·斯蒂芬斯
1.1 算法和数据结构
-
算法是完成某个任务的方法。
-
数据结构是一种安排数据的方法。这个方法使解决某个特定的问题更简单。数据结构可以是一种在数组中放置数据的方法,一个以某种特定结构链接物体的链表,一棵树,一个图,一个网络等等。
-
通常一个算法意味着:”建立一个特定的数据结构,然后用一个特定的方法使用它“
-
没有数据结构就没有算法。
-
如果不打算在算法中运用数据结构,那么设计这个算法也就没有意义
1.2
算法的特点:正确性,可维护性,效率
1.3大O符号
大O符号使用函数来描述数据规模增长到很大时算法的最坏性能是如何与问题规模相关的(这有时称为程序的渐进性能)。这个函数写在大写字母O后面的括号里。
计算算法的大O符号有5个基本的规则:
- 如果一个算法对于一个数学函数f执行一系列的步骤f(N)次,他需要O(f(N))步
- 如果一个算法对于函数f执行了一个需要O(f(N))步的操作,然后对于函数g执行了第二个需要O(g(N))步的操作,这个算法的总体复杂度为O(f(N)+g(N))。
- 如果一个算法的复杂度是O(f(N)+g(N)),并且对于足够大的N,函数f(N)远大于g(N),这个算法的性能可以被简化为O(f(N))。
- 如果一个算法执行了一个需要O(f(N))步的操作,对于操作中的每一步执行了另外的O(g(N))步,这个算法的总体复杂度为O(f(N)*g(N))。
- 忽略常数的倍数。如果C是一个常数,O(Cf(N))等同于O(f(N))。并且O(f(CN))等同于O(f(N))。
“大O符号只是为了让你了解算法的理论性能”
1.4常见的运行时间的函数
- 复杂度为O(1)的算法
复杂度为一的算法使用常数的时间,无论问题的规模多大 - 复杂度为O(logN)的算法
这种算法通常在每一步中把它必须考虑的元素的数量除以一个固定的因数。 - 复杂度为O(sqrt(N))的算法
sqrt是平方根函数 - 复杂度为O(N)的算法
- 复杂度为O(N log N)的算法
假设一个算法遍历其输入中的所有元素,然后在每一个循环中,对那个元素执行了某种复杂度为O(log N)的计算。在这种情况下,这个算法的复杂度是O(N*log N)或O(N log N)。
另外,一个算法执行某种复杂度为O(log N)的操作,在这之中的每一步,对这个输入中的元素都执行操作。 - 复杂度为O(N^2)的算法
一个算法遍历所有的输入,然后对每一个输入都再次遍历每一个输入的操作时间复杂度就是O(N^2)。 - 复杂度为O(2^N)的算法
- 复杂度为O(N!)的算法