期末考试形式全为大题,重点在于概念的掌握和方法的描述,所以再根据考点进行比较概念层面的复习
第一章
1、算法具有四个属性:
有输入,有输出,确定性,有穷性
第二章
一、分治法
> 分治法的设计思想: 将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
> 分治法能解决问题的特征:
该问题的规模缩小到一定的程度就可以容易地解决;
该问题可以分解为若干个规模较小的相同问题,即该问题具有最优
子结构性质利用该问题分解出的子问题的解可以合并为该问题的解;(重要条件!)
该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
二、递归
> 直接或间接地调用自身的算法称为递归算法。用函数自身给出定义的函数称为递归函数。
> 每个递归函数必须有非递归定义的初始值
> 边界条件与递归方程是递归函数的二个要素,递归函数只有具备了这两个要素,才能在有限次计算后得出结果
三、二分搜索(找出中间元素比对,二分搜索数组)
> 算法复杂度分析:每执行一次算法的while循环, 待搜索数组的大小减少一半。因此,在最坏情况下,while循环被执行了O(logn) 次。循环体内运算需要O(1) 时间,因此整个算法在最坏情况下的计算时间复杂性为O(logn) 。
四、快速排序
> 最坏时间复杂度: O(n2). 平均时间复杂度: O(nlogn). 辅助空间: O(n)或O(logn)
第三章
一、动态规划
> 动态规划算法的基本要素:最优子结构和重叠子问题
> 动态规划算法思想:与分治法类似,其基本思想也是将待求解问题分解成若干个子问题
二、矩阵连乘
> 计算量: A[i:k]的计算量加上A[k+1:j]的计算量,再加上A[i:k]和A[k+1:j] 相乘的计算量
m[i,j] = m[i,k] + m[k+1,j] + p^(i-1)p^kp^j
> 特征:计算A[i:j]的最优次序所包含的计算矩阵子链 A[i:k]和A[k+1:j]的次序也是最优的。矩阵连乘计算次序问题的最优解包含着其子问题的最优解。这种性质称为最优子结构性质。
> 算法复杂度分析:算法matrixChain的主要计算量取决于算法中对r,i和k的3重循环。循环体内的计算量为O(1),而3重循环的总次数为O(n3)。因此算法的计算时间上界为O(n3)。算法所占用的空间显然为O(n2)。
三、0-1背包(动态规划)
> 算法复杂度分析: O(nc).改进后算法的计算时间复杂性为O(2^n)
四、最优二叉树
> 定义:
(1)若它的左子树不空,则左子树上所有
节点的值均小于它的根节点的值;
(2)若它的右子树不空,则右子树上所有
节点的值均大于它的根节点的值;
(3 它的左、右子树也分别为二叉排序树
> 时间复杂度:O(n2)
五、贪心算法
> 定义:贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。
> 性质:贪心选择性质和最优子结构性质。
> 和动态规划的区别:动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行
第四章
一、哈夫曼编码
> 定义:给出现频率高的字符较短的编码,出现频率较低的字符以较长的编码,可以大大缩短总码长。
> 时间复杂度:为O(nlogn) 。
二、 最小生成树
1、Prim算法
> 定义:根据已更新的数据选取最短路径
> 时间复杂度: O(n^2)
2、 Kruskal算法
> 定义:选择最小的边,但是不成圈
> 时间复杂度:当图的边数为e时,Kruskal算法所需的计算时间是O(eloge) 。
第五章
一、回溯法(深度优先搜索策略)
> 解空间:对于问题的一个实例,解向量满足显式约束条件的所有多元组,构成了该实例的一个解空间。
n=3时的0-1背包问题用完全二叉树表示的解空间
> 定义:具有限界函数的深度优先生成法称为回溯法
> 剪枝函数:用约束函数在扩展结点处剪去不满足约束的子树;用限界函数剪去得不到最优解的子树。
二、N后问题
> 定义:在n×n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上
解向量:(x1, x2, … , xn)
显约束:xi=1,2, … ,n
隐约束:
1)不同列:xixj
2)不处于同一正、反对角线:|i-j||xi-xj|
> 注意:解空间存在4^4种可能的解!必须使用剪枝函数
三、0-1背包(回溯法)
> 解空间:子集树.上界函数:cp+rbestp
四、旅行售货员问题(回溯法)
> 解空间:排列树
> 复杂度分析:整个算法的计算时间复杂性为O(n!)。
五、回溯法效率分析
> 回溯算法的效率在很大程度上依赖于以下因素:
(1)产生x[k]的时间;
(2)满足显约束的x[k]值的个数;
(3)计算约束函数constraint的时间;
(4)计算上界函数bound的时间;
(5)满足约束函数和上界函数约束的所有x[k]的个数。
> 在选择约束函数时通常存在生成结点数与约束函数计算量之间的折衷
第六章
一、分支限界法
> 定义:
(1)求解目标:回溯法的求解目标是找出解空间树中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出在某种意义下的最优解。
(2)搜索方式的不同:回溯法以深度优先的方式搜索解空间树,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间树。
> 常见的两种分支限界法:
(1)队列式(FIFO)分支限界法(队列先进先出(FIFO))
(2)优先队列式分支限界法(选取优先级最高的节点成为当前扩展节点)
二、0-1背包(分支限界法)
> 首先,要对输入数据进行预处理,将各物品依其单位重量价值从大到小进行排列。节点的优先级由已装袋的物品价值加上剩下的最大单位重量价值的物品装满剩余容量的价值和。
三、旅行售货员(分支限界法)
> 定义:算法开始时创建一个最小堆,用于表示活结点优先队列。堆中每个结点的子树费用的下界lcost值是优先队列的优先级。接着算法计算出图中每个顶点的最小费用出边并用minout记录。如果所给的有向图中某个顶点没有出边,则该图不可能有回路,算法即告结束。如果每个顶点都有出边,则根据计算出的minout作算法初始化。
第七章
一、随机化算法
> 定义:允许算法在执行过程中随机选择下一个步骤,不做最优决策。复杂度低。
二、随机数(线性同余法)
> 定义:在现实计算机上无法产生真正的随机数,因此在随机化算法中使用的随机数都是一定程度上随机的,即伪随机数。
数值随机化算法(求圆周率、定积分)
double Darts(int n) {
//用随机投点法计算π值
static RandomNumber dart;
int k = 0;
for (int i = 1; i <= n; i++) {
double x = dart.fRandom();
double y = dart.fRandom();
if ((x*x + y*y) <= 1) k++;
}
return 4 * k / double(n);
}
double Darts(int n) {
//用随机投点法计算定积分
static RandomNumber dart;
int k = 0;
for (int i = 1; i <= n; i++) {
double x = dart.fRandom();
double y = dart.fRandom();
if (y <= f(x)) k++;
}
return k / double(n);
}