算法分析
- 存储方式:顺序存储、链式存储、索引存储、散列存储
- 程序=数据结构(待处理的信息)+算法(处理信息的步骤)
- 算法的特点:有穷性、确定性、可行性、输入、输出
- 好算法的特点:正确性、可读性、健壮性、高效率与低存储(即时间和空间复杂度都要低)
1. 时间复杂度
-
比较:由小到大,“常对幂指阶”
-
加法规则:$O(f(n))+O(g(n)) = O(\max(f(n),g(n)))$
- 乘法规则:$O(f(n))\times O(g(n)) = O(f(n)\times g(n))$
- 扩展递归技术:用于求解递推关系式。扩展就是根据递推式替换等式右边项,依此下去,会得到一个求和表达式,求和得到问题的解。
- 对于一个分治/递归算法,列出关系式(比如f(n)=...f(n/2)...,或者f(n)=...f(n-1)...)。
- 确定最小规模(比如$n/2^k=1$或$n-k=1$),使得右边的项最小只能到f(1),算出k等于多少
- 从第0层开始,一直替换到最小规模(即第k层)
- 累加:从第0层加到第k层,算时间复杂度,其中,T(1)=O(1)
- 主定理:若有$T(n)=aT(\frac{n}{b})+f(n),其中a\ge1,b\gt1$
- 其中,假设每个子问题的规模都一样为$\frac{n}{b}$,f(n)为递归以外的计算,$\epsilon>0$,$c<0$
- 小于关系:若$f(n)=O(n^{\log_b a-\epsilon})$,则$T(n)=O(n^{lon_b{a}})$
- 等于关系:若$f(n)=\Theta(n^{\log_ba})$,则$T(n)=O(n^{lon_b{a}}\log n)$
- 大于关系:若$f(n)=\Omega(n^{\log_b a+\epsilon})$,若$af(n/b)\le cf(n)$,则$T(n)=O(f(n))$
- 注意,大于关系有两个条件
2. 空间复杂度
- 同上
线性表
- 分配方式:静态分配(大小固定)、动态分配(malloc+free)
- 数组实现
- 链表实现
哈希表
- 哈希函数
- 冲突
- 拉链法实现
- 闭散列法实现
栈和队列
1. 栈与队列
- 数组模拟
- 链表模拟
2. 单调栈
- 在一个栈中维护一个递增/递减序列


3. 单调队列
- 在一个双端队列中维护一个递增/递减序列

4. 优先队列(堆)
- 注:以下以大根堆为例
- 原子操作
- 向上调整:O(logn),如果结点权值大于父亲,则交换。
-
向下调整:O(logn),如果结点小于最大的儿子,则交换。
-
插入操作=最后一个结点之后插入+向上调整
- 删除操作=根结点与最后一个结点对调+向下调整
- 增加权值=直接修改+向上调整
- 建堆:使用若干次插入操作(即向上调整法来建堆)