算法
1. 算法的基本概念
对于给定问题,算法就是用计算机求解这个问题的方法。一般来说,一个算法具有有限条指令构成,每条指令规定了计算机所要执行的有限次运算或操作。
定义:
- 定义 问题:需要回答的一般性提问,通常含有若干参数,为了清晰地描述一个问题,需要说明参数的含义和解所满足的条件。如果对问题参数给出一组赋值,就得到了一个问题的实例
- 定义 算法:有限条指令序列,这个指令序列确定了解决某个问题的运算或操作的步骤。算法 解决问题 指的是:把问题 的任何实例作为算法 的输入, 能够在有限步停机,并输出该实例的正确解
- 定义 算法的时间复杂度:对于算法的效率的度量,一般做法是针对问题选择基本运算,用基本运算次数来表示算法的效率,运算符次数越多,效率就越低。这还和数据的规模和数据的具体内容有关,详细定义参见 TODO 复杂度分析。
定义 最坏情况下的时间复杂度 为 ,代表该算法求解输入规模为 的实例所需的最长时间。
定义 平均情况下的时间复杂度 为 ,代表了该算法求解输入规模为 的实例所需的平均时间。
2. 伪代码编写
定义 伪代码 是方便人理解和分析的代码,而非一定可执行的代码。伪代码通常用于分析问题,忽略了真实的实现细节。伪代码应该专注于算法的设计与分析,具体的实现应该由具体的语言编写。
定义符号:
- 赋值语句: 或者
- 分支语句:
- 循环语句:
- 跳转:
- 输出语句:
- 注释:
伪代码的语句通常有标号,这也是为了分析和表示方便。
有时,伪代码可以直接使用自然语言描述出来,伪代码不定义什么是非法语句。如果前面已经实现了某种算法,后面需要的时候可以直接使用自然语言描述。常见的操作也可以使用自然语言描述。
例如, 算法用于计算 和 的最大公约数:
算法:
输入:非负整数 ,其中 与 不全为
输出: 与 的最大公约数
3. 算法的数学基础
关于程序的复杂度表示请参考 TODO 复杂度分析。
3.1 函数的渐进的界
给出下列定义:
- 定义 若存在正数 和 使得对于 有 成立,则称 的 渐进的上界 是 ,记作
- 定义 若存在正数 和 使得对于 有 成立,则称 的 渐进的下界 是 ,记作
- 对于任意正数 都存在 ,使得 时有 成立,则
- 对于任意正数 都存在 ,使得 时有 成立,则
- 且 ,则记作
@theorem 设 和 是定义域为自然数集 上的非负函数,那么有:
- 如果 存在,并且等于某个常数 ,那么
- 如果 ,那么
- 如果 ,那么
@theorem 设 是定义域为自然数集 上的函数,那么有:
- 如果 且 ,那么
- 如果 且 ,那么
- 如果 且 ,那么
@theorem 设 和 是定义域为自然数集 上的函数,若对于某个其他函数 ,有 和 ,那么 。
@theorem 对于每个 和每个 ,有 。
对数的另一条性质是:对于不同的底 与 ,,只需要使用对数的基本恒等式
即可证明。通常我们以 指以 为底的对数。
@theorem 对于每一个 和每一个 ,有 。
阶乘函数 是增长很快的函数,根据 斯特林公式,阶乘函数
关于阶乘函数有下面的结果:
阶乘
运算符 的优先级大于加减乘除和其他常见运算符。
下面列举常见函数的界的大小比较结果,从高到低排序:
函数 |
---|
取整函数也是常见的一类函数,向下取整函数 相当于 C 语言的 floor(x)
,向上取整函数 相当于 C 语言的 ceil(x)
。
取整函数具有下列性质:
- ,,其中 为整数
- ,其中 为整数
- ,,其中 为整数
关于算法中常见的函数,其他章节也会进行讨论。