> For the complete documentation index, see [llms.txt](https://zg-zhang.gitbook.io/note/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://zg-zhang.gitbook.io/note/shu-ju-jie-gou/1.md).

# 算法

> 算法 Algorithm：算法是解决特定问题求解步骤的描述，在计算机中表现为指令的有限序列，并且每条指令表示一个或多个操作。

## 算法的特性

算法具有五个特性：输入、输出、有穷性、确定性和可行性

* 输入：算法具有零个或多个输入
* 输出：算法至少有一个或多个输出
* 有穷性：算法在执行有限的步骤之后，自动结束而不会出现无限循环，并且每一个步骤在可接受的时间内完成
* 确定性：算法的每一步骤都具有确定的含义，不会出现二义性
* 可行性：算法的每一步都必须是可行的，也就是说，每一步都能通过执行有限次数完成

## 算法设计的要求

* 正确性：算法的正确性是指算法至少应该有输入、输出和加工处理无关歧义性、能正确反映问题的需求、能够得到问题的正确答案。

算法的正确通常在用法上有很大差别，大体分为以下四个层次：

1. 算法程序没有语法错误
2. 算法程序对于合法的输入能够产生满足要求的输出结果
3. 算法程序对于非法的输入能够得出满足规格说明的结果
4. 算法程序对于精心选择的、甚至刁难的测试数据都有满足要求的输出结果

其中 1 最简单 4 最困难，但是我们几乎不可能注意验证所有的输入都得到正确的结果，所以我们通常把 3 作为一个算法是否正确的标准

* 可读性：算法设计的另一个目的是为了便于阅读、理解和交流
* 健壮性：当输入数据不合法时，算法也能做出相关处理，而不是产生异常或莫名奇妙的结果
* 时间效率高和存储量低：设计算法应该尽量满足时间效率高和存储量低的需求

## 算法效率的度量方法

* 事后统计方法：通过设计好的测试程序和数据、利用计算机计时器对不同算法编制的程序的运行时间进行比较，从而确定算法效率的高低

但是这种方法有很大缺陷，实际中不考虑采纳：

1. 必须依据算法事先编制好的程序
2. 时间的比较依赖计算机硬件和软件等环境因素，有时会掩盖算法本身的优劣
3. 算法的测试数据设计困难，并且程序的运行时间往往还与测试数据的规模有很大关系
4. 事前分析估算法：在计算机程序编制前，依据统计方法对算法进行估算

抛开与计算机硬件、软件有关的因素，一个程序的运行时间，依赖于算法的好坏和问题的输入规模

测定运行时间最可靠的方法就是计算对运行时间有消耗的基本操作的执行次数，运行时间与这个计数成正比

最终，在分析程序的运行时间时，最重要的是把程序看成是独立于程序设计语言的算法或一系列步骤

## 函数的渐近增长

> 函数的渐近增长：给定两个函数 f(n) 和 g(n)，如果存在一个整数 N，使得对于所有的 n > N，f(n) 总是比 g(n) 大，那么我们说 f(n) 的增长渐近快于 g(n)

判断一个算法的效率时，函数中的常数和其他次要项常常可以忽略，而更应该关注主项（最高次项）的阶数

某个算法，随着 n 的增大，它会越来越优于另一个算法，或者越来越差于另一个算法

## 算法时间复杂度

> 在进行算法分析时，语句总的执行次数 T(n) 是关于问题规模 n 的函数，进而分析 T(n) 随 n 的变化情况并确定 T(n) 的数量级。 算法的时间复杂度，也就是算法的时间量度，记住：T(n) = O(f(n))。 它表示随问题规模 n 的增大，算法执行时间的增长率和 f(n) 的增长率相同，称作算法的渐近时间复杂度，简称为时间复杂度。 其中 f(n) 是问题规模 n 的某个函数
