算法总结
Contents
这是个课程总结.
1. 分治法
适用条件
- 原问题可以分解为若干个与原问题性质相类似的子问题
- 问题的规模缩小到一定程度后可方便求出解
- 子问题的解可以合并得到原问题的解
- 分解出的各个子问题应相互独立,即不包含重叠子问题
基本步骤
- 分解问题(divide):把原问题分解为若干个与原问题性质相类似的子问题
- 求解子问题(conquer):不断分解子问题直到可方便求出子问题的解为止
- 合并子问题的解(combine):合并子问题的解得到原问题的解
相关算法
- 归并排序
- 最好情况:
- 最坏情况:
- 快速排序
- 最好情况:
- 最坏情况: (相同元素, 或者已经有序)
2. 动态规划
必要前提
- 最优子结构性质: 一个问题的最优解中所包含的所有子问题的解都是最优的
- 重叠子问题: 不是必要前提, 但存在重叠子问题可以提高算法效率
基本步骤
- 确定问题的最优子结构
- 递归定义最优解值
- 自底向上计算最优解值
- 从已计算得到的最优解值信息中构造最优解
相关算法
- 矩阵链乘法
- 最长公共子序列问题 , m,n为两序列长度
- 最优二叉查找树
3. 贪心算法
必要前提
- 最优子结构性质: 局部最优+一系列贪心选择产生原问题的一个最优解
- 贪心选择性质: 所求问题的最优解可以通过一系列局部最优的贪心选择而得到。即:局部最优->全局最优. 贪心选择性质是区别与动态规划方法的一个重要特征, 因为贪心法在作出选择时并不依赖于将来的情况, 只需根据当前的情况即可作出选择。
基本步骤
- 确定问题的最优子结构
- 将优化问题转化为作出一种选择,即贪心选择
- 贪心选择后应只留下一个子问题,其它子问题均为空
- 证明贪心选择的正确性,即本次贪心选择与剩余子问题的最优解可以构成原问题的最优解
贪心算法与动态规划的比较
- 贪心法效率更高,表现在子问题不需要都计算,而选择数为1。
- 动态规划方法的应用面更广,问题只需具有最优子结构即可,而贪心法不仅需要具有最优子结构性质,还需要具有贪心选择性质
相关算法
- 活动选择问题(Recursive-Activity-Selector)
- Huffman编码: 采用二叉堆管理序列,
胚的概念
- 胚, 是有限集, 是的独立子集构成的集合族:
- 独立性: 每个独立集的子集也是独立的. 即任何, 如果 , 则
- 交换性: 如果和是的两个独立集,比有更多的元素, 则在中存在一个元素,当其加入时得到一个比更大独立集.
- 最大独立子集: 若是的独立子集即, 如果存在一个元素, 且 , 则称为的一个扩展. 如果A不存在扩展就称为最大独立子集
- 加权胚: 为中每个元素赋予一个权重, 对于集合, 其中每个元素乘以各自的权重得到的就是的权值, 即:
- 最优子集: 使权值达到最大的独立子集A称为最优子集. 若是的独立子集, 由于任何元素的权重都是正数, 故最大独立子集具有最大权重, 最优子集 = 最大独立子集
4. 渐进记号
- : 是的上界
- : 下界
- : 紧确界
- : 不紧确上界
- : 不紧确下界
5. 主方法
比较和:
- 情况1: ,
- 情况2: ,
- 情况3: , 且对某个常数c<1存在足够大的n使得, 则
6. 红黑树
二叉查找树
- 假设n为节点数, h为树高, 则h最低为, 最高为n
- 静态操作: 查找结点、找前驱、后继等时间为O(h)
- 动态操作: 插入和删除结点等时间为O(h)
红黑树
- 查找、插入、删除: O(h)
- 插入最多旋转2次, 删除最多旋转3次
序统计树
定义: 所谓序统计就是在一系列数中找出最大、最小值,某个数的序值等操作
- 找第i个最小值操作: O(lgn)
- 求x的序值操作: O(lgn)
- 插入或删除操作: O(lgn)
区间树
- i与i’重叠可描述为:
- 插入和删除操作: O(lgn)
数据结构扩张的步骤
- 挑选一个合适的基本数据结构
- 决定在基本数据结构上应增加的信息
- 修改基本数据结构上的操作并维持原有的性能
- 修改或设计新的操作
7. 平摊分析
####势函数方法 先证明势函数恒为正, 再计算平摊代价
- 栈操作
- 二进制计数器
- 动态表扩张/收缩
8. 二项堆
性质
- 最小堆性质: 节点关键字大于父节点关键字
- 没有度数相同的根. 使用二进制表示每个根, 那么每一位的大小就是结点个数, 因此n个结点最多有lgn+1颗二项树
- 根表: 单链表, 根的度数严格递增
算法性能:
|算法|性能(最坏)|备注| |:-:|:-:| |建堆|O(1)| |寻找最小关键字||沿着根表寻找最小值| |合并两个二项堆||维护两个指针, 连接两个度数相同的根,跳过三个度数相同的根里的第一个| |插入节点||先构造一个节点的二项堆,再合并| |抽取最小节点||删除根, 将子树逆序排列, 再与剩下的堆合并| |减少关键字的值||如果比父节点小就交换,直到比父节点大| |删除节点||先减少到最小, 再抽取最小节点|
9. 斐波那契堆
性质
- 根表: 环形双链表, 指向最小值
算法性能
操作 | 性能(平摊) | 备注 |
---|---|---|
抽取最小节点 | O(lgn) | 合并度数相同的根 |
删除节点 | O(lgn) | |
减值 | O(1) | 先检查是不是根节点, 不是若违背最小堆性质就删掉再把子树合并 |
其他操作都是O(1) |