第一章:
1、什么是算法:
(1)算法是解决问题的一种方法和过程
(2)算法是若干指令的有穷序列
2、算法的性质:
(1)输入:有外部提供的量作为算法的输入。
(2)输出:算法产生至少一个量作为输出。
(3)确定性:组成算法的每条指令是清晰
(4)有限性:算法中每条指令的执行次数和时间是有限的
3、算法复杂度的表示方法,含义
(1)大O:算法的渐进上界,上界的阶越低,则评估越精确,结果就越有价值。
(2)欧母:算法的渐进下界,这个下界的阶越高,则评估越精确,结果就越有价值。该渐进符号一般用于描述算法的最优复杂度
(5)θ:界定函数的渐进上界和渐进下界
4、最好、最坏、平均时间复杂度:
(1)最坏时间复杂性(最糟糕的情况执行代码的时间复杂度。如在数组中查找不存在的变量x,需要将整个数组遍历一遍)
Tmax(n) = max{ T(I) | size(I)=n }
一般用最坏时间复杂度讨论算法的时间复杂度,因为最坏情况下的时间复杂度是算法在任何输入实例上运行时间的界限,保证了算法的运行时间不会比最坏情况更长。
(2)最好时间复杂性(最理想的情况执行代码的时间复杂度。如要查找的变量x正好是数组的第一个元素)
Tmin(n) = min{ T(I) | size(I)=n }
- 平均时间复杂性(所有可能输入实例均以等概率出现的情况下,该算法的运行时间)
I是问题的规模为n的实例,p(I)是实例I出现的概率。
第二章:
1、什么是递归:
直接或间接地调用自身的算法称为递归算法。
递归:在一个过程或函数的定义时出现调用本过程或本函数的成分
2、两种递归直接和间接
· 直接(自)递归:在函数中调用函数自身或在过程的子部分中调用子部分自身的内容
· 间接递归:不同的函数和子过程之间互相调用
3、二分搜索 归并排序 快速排序
(1)二分搜索:给定已排好序的n元素a[0:n-1],在n元素中找出一特定元素x。
基本思想:将n个元素分成大致相同的两半,取a[n/2]与x进行比较。
(2)合并排序:用分治策略实现对n个元素进行排序的算法
基本思想:将待排序的数组元素分割成大小相同的2个子集合,分别对两个子集合进行排序,将排好序的子集合并
(3)快速排序:从两端向中间进行比较,关键字较大的记录一次就能交换到后面单
元,关键字较小的记录一次就能交换到前面单元,记录每次移动的距离较大,总的比较和移动次数较少。
4、分治法的基本思想
将一个规模为n的问题分解为k个规模较小的子问题,子问题互相独立且与原问题相同。递归地解子问题,将各子问题的解合并得到原问题的解。
第三章:
1、动态规划(DP)的基本要素:
最优子结构:最优解包含着其子问题的最优解
重叠子问题:递归算法求解问题时,每次产生的子问题并不总是新问题,有些子问题被反复计算多次。
2、动态规划算法的步骤:
找出最优解的性质,并刻画其结构特征
递归的定义最优值
以自底向上的方式计算最优值
根据计算最优值时得到的信息构造最优解
3、动态规划(DP)与分治法的区别:
(1)分治法分解后的子问题相互独立,动态规划分解后的子问题有相互联系和重叠
(2)分治法利用递归求解。动态规划利用迭代法自底向上求解,用具有记忆功能的递归法自顶向下求解
4、矩阵连乘
5、LCS最长公共子序列
6、最大子段和
7、01背包
第四章:
1、贪心算法的基本思想:
贪心算法并不从整体最优考虑,在某种意义上的局部最优选择。
贪心算法首先设计某种贪心选择策略,第一步做出当前状态的最优选择;然后问题会被演化为与原问题相同但规模更小的子问题,最后用相同的贪心选择策略求解子问题。
2、贪心算法的基本要素
贪心选择性质:所求问题的整体最优解可以通过一系列局部最优解来达到。
最优子结构性质:当一个问题的最优解包含其子问题的最优解
3、贪心与DP的差异
(1)贪心选择:所求问题的整体最优解可以通过一系列局部最优的选择达到
(2)动态规划算法通常以自底向上的方式解各子问题,贪心算法自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。
4、最优装载
5、哈夫曼编码
- 活动排工
第五章:
1、常用回溯法的算法框架:
2、递归回溯
void backtrack (int t){//t为递归深度,即当前扩展节点在解空间树中的深度;
if (t > n) //n用来控制递归深度
output(x);//算法已搜索至叶结点
else{
for (int i = f(n,t); i <= g(n,t); i++){//f(n,t)、g(n,t)分别表示在当前扩展节点处未搜索过的子树的起始编号和终止编号
x[t] = h(i);//h(i)表示在当前扩展结点处x[t]的第i个可选值
if (constraint(t) && bound(t))//constraint(t)和bound(t))分别是当前扩展结点处的约束函数和限界函数
//constraint(t)返回true表示在当前扩展结点处x[1:t]取值满足问题的约束条件,为false表示不满足约束条件,可剪去相应的子树。
//Bound返回true说明在x[1:t]取值未使目标函数越界,还可以继续由backtrack(t+1) 继续对其子树进一步搜索。Bound返回true ,说明已越界,可以剪去其子树
backtrack(t+1);
3、迭代回溯
树的非递归深度优先遍历算法
void iterativeBacktrack (){
int t=1;
while (t > 0) {
if ( f(n,t) <= g(n,t))
for (int i = f(n,t); i <= g(n,t); i++) {
x[t] = h(i);
if (constraint(t) && bound(t)) {
if (solution(t))
output(x);
else t++;
}
}
else t--;
第六章:
1、队列:
2、优先队列:
3、回溯和分支限界的共同点和不同点,提高算法效率的关键