(一)插入排序
时间复杂度:
原址排序,只需要一个key,稳定排序算法
插入排序是随机访问模型(random access machine->RAM)
RAM常见指令:算数指令(加减乘除取余取模)、数据移动指令(装入、存储、复制)、控制指令(条件与无条件转移、子程序调用与返回)
(二)归并排序:
分解(divide):分解待排序的n个元素的序列成各具n/2个元素的两个子序列
解决(conquer):使用归并排序递归地排序两个子序列
合并(combine):合并两个已经排序的子序列 以产生已排序的答案
时间复杂度:
渐进记号(asymptotic)
只有渐进上界用O(n),表示:所有在cn函数下方的函数集合
(三)分治法
求最大子数组(maximum subarray)
找到2个规模尽量相等的子数组,即找到子数组中点位置即为mid。递归求解A[low..mid] A[mid+1..high]的最大子数组
图(a)表示:最大子数组可能存在的3种位置
(四)求解递归(recurrence)
1、 代入法(substitution)
2、 递归树法
3、 主方法
(五)堆排序:
1、维护最大堆性质,时间复杂度:
2、建堆
3、 堆排序算法 不稳定
(六)优先队列(priority queue)
1、 返回s中具有最大键值的元素
2、 去掉并返回s中的具有最大键字的元素
3、 将元素x的关键字值增加到k,(假设k的值不小于x的原关键字值)
(七)快速排序(分治思想)
1、普通版
原址排序,时间复杂度:
2、随机版
(八)线性时间排序
比较排序——> 在排序的最终结果中,各元素的次序依赖于他们之间的比较。比较排序在最坏的情况下要经过Ω(nlgn)次比较。堆排序和归并排序都是渐进最优的比较排序方法。
1、决策树模型
2、计数排序(counting-sort)
稳定;时间复杂度:
计数排序被用于计数排序的子过程。
3、基数排序(radix sort)
非原址排序;一位数排序算法必须是稳定的;时间复杂度:
4、 桶排序(bucket sort)
(九)动态规划
最优子结构(optimization solution)+重叠子问题(overlapping subproblem)
动态规划的两种等价实现方法:
(1) 带备忘的自顶向下(top-down with memoization)
按递归形式编写,但过程中会保存每个子问题的结(通常列在一个数组或算了吧中)。当需要一个子问题的解时,先减产是否已经保存过此解。如果是,则直接返回保存的值,从而节省计算时间;否则按通常方式计算此子问题。
(2) 自底向下(bottom-up method)
将子问题按规模排序,由小到大求解。每个子问题都只用求解一次。
1、 钢条切割
(1) 自顶向下加入备忘
(2) 自底向上
重构解
2、 矩阵链乘
(1) 自底向上表格法
构造最优解
优化核心算法(加入递归):
(2) 带备忘的自顶向下
3、 无权最短路径:找到一条从u到v边数最少的路径。有最优子结构。
4、 无权最长路径:无最优子结构。
5、 最长公共子序列
计算LCS长度(long-common-subsequence 子序列 & substring子串ß必须连续)
构造LCS
6、 0-1背包
I的值是---装了几个物品
J的值是---现在背包的容量
存的元素---现在的价值
令V(i,j)表示在前i(1<=i<=n)个物品中能够装入容量为j(1<=j<=C)的背包中的物品的最大价值,则可以得到如下的动态规划函数:
(1) V(i,0)=V(0,j)=0
(2) V(i-1,j) j<wi
V(i,j)=
max{V(i-1,j) ,V(i-1,j-wi)+vi) } j>wi
(1)式表明:如果第i个物品的重量大于背包的容量,则装入前i个物品得到的最大价值和装入前i-1个物品得到的最大价是相同的,即物品i不能装入背包;
(2)式表明:如果第i个物品的重量小于背包的容量,则会有一下两种情况:
(a)如果第i个物品没有装入背包,则背包中物品价值就等于把前i-1个物品装入容量为j的背包中所取得的价值。
(b)如果把第i个物品装入背包,则背包物品的价值等于第i-1个物品装入容量位j-wi 的背包中的价值加上第i个物品的价值vi;
显然,取二者中价值最大的作为把前i个物品装入容量为j的背包中的最优解。
打印出当前的v数组和被选中物品的x数组。
7、 求最大子段和
B数组记录了以当前元素为结尾时,最大字段的和,用第一个循环完成。
第二个循环,打印B数组。
第三个循环,遍历B数组,找到最大值。
(十)贪心算法
最优子结构+贪心性选择
1、 活动选择问题
2、 部分背包
(1)构造并输出二维数组b数组。第一行:单位重量的价值增序;第二行:对应的重量;第三行:对应的价值。(2)构造并输出x数组贪心性选择是单位重量的价值最大的。(3)根据b和x数组计算最大价值s并输出。
3、 赫夫曼编码
每个步骤合并频率最低的两颗树
(十一)单结点对
1、 bellman-ford
Bellman-ford算法在求解过程中,每次循环每个顶点的dist[]值都有可能要修改,也就是说源点到各顶点最短路径长度一直要到Bellman-ford算法结束才确定下来。
2、 dijkstra(贪心算法)
贪心性选择:选择集合V-S中“最轻”或“最近”的结点来加入集合S中。每次选择结点u来加入到集合S中时,有
Dijkstra在求解过程中,源点到集合S内各顶点的最短路径一旦求出,则不变化了,修改的仅仅是从源点到T集合中个顶点的最短路径长度。
(十二)所有结点对
1、 最短路径和矩阵乘法(动态规划)
自底向上
改进
2、 Floyd-warshall(动态规划)
3、 Johnson(给予稀疏矩阵)
(十三)回溯法
问题状态(problem state)解决问题时,树中的一个节点定义了一个问题状态
状态空间(state space)所有从根到结点的路径(蛮力法)
解状态(solution state)满足显式约束
答案状态(answer state)同时满足隐式约束
状态空间树 E-node(扩展结点)可以继续生成孩子结点的结点
Alive-node(活结点)被DFS,此结点在等待生成结点
Dead-node(死结点)不能生成孩子结点的结点
限界函数bound-function:不生成全部problem state—》杀死一部分活结点
1、8-Queen
2、给定n+1个整型,找子集使和为M (DFS)
3、0-1背包
对一组数据,有两种可能:选或不选,在树种用左右字数表示。
使用递归,在遍历完n个数时,判断最终的数是否比最佳价值大,如比最佳大,则把值付给besrv。
上界函数:当前的价值cw+剩余可容纳的最大价值<=当前最优解
(十四)分支限界
15-Puzzle (BFS)
定理:是偶数,则可达。
ĉ(X)=f(X)+ĝ(X)代价估计函数。
f(X) is the length of the path from the root to X
ĝ(X) is the minimum number of movings from X to the target state.
ĝ(X)=the number of blocks which are not in its target position (except the blank space)
(十五)NP问题,
Computability
Undecidable Problem
Hilbert’s 10th Problem.
Post’s Correspondence Problem.
Halting Problem.
NP-Complete
P, EXP, NP, NP-Complete
SAT is the first NP-Complete problem
Other NP-Complete problems: 3-color, TSP, CIRCUIT-SAT