《算法基础》复习提纲
文章目录
1 引言(ch1)
-
什么是算法及其特征,理解算法的基本概念
算法就是问题的程序化解决方案。
算法就是一个定义良好的计算过程,它取一个或者一组值作为输入,并产生出一个或者一组值作为输出。即,算法就是一系列的计算步骤,用来将输入数据转换成输出结果。
-
问题实例和问题规模
输入实例:问题的具体计算例子
问题规模:算法的输入实例大小
2 算法初步(ch2)
分治法(子问题必须相互独立)必考,一般只用分析最坏运行时间
-
插入排序算法
-
算法复杂性及其度量
- 时间复杂性和空间复杂性;
- 最坏、最好和平均情形复杂性;
-
插入排序的最坏、最好和平均时间
-
归并排序算法及其时间复杂性
归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用**分治法(Divide and Conquer)**的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
基本思路:
先递归的把数组划分为两个子数组,一直递归到数组中只有一个元素,然后再调用函数把两个子数组排好序,因为该函数在递归划分数组时会被压入栈,所以这个函数真正的作用是对两个有序的子数组进行排序;
基本步骤:
1、判断参数的有效性,也就是递归的出口;
2、首先什么都不管,直接把数组平分成两个子数组;
3、递归调用划分数组函数,最后划分到数组中只有一个元素,这也意味着数组是有序的了;
4、然后调用排序函数,把两个有序的数组合并成一个有序的数组;
5、排序函数的步骤,让两个数组的元素进行比较,把大的/小的元素存放到临时数组中,如果有一个数组的元素被取光了,那就直接把另一数组的元素放到临时数组中,然后把临时数组中的元素都复制到实际的数组中;
**归并的时间复杂度分析:**主要是考虑两个函数的时间花销,一、数组划分函数mergeSort();二、有序数组归并函数_mergeSort();
mergeSort()函数的时间复杂度为O(n),因为代码中有2个长度为n的循环(非嵌套),所以时间复杂度则为O(n);
简单的分析下元素长度为n的归并排序所消耗的时间 T[n]:调用mergeSort()函数划分两部分,那每一小部分排序好所花时间则为 T[n/2],而最后把这两部分有序的数组合并成一个有序的数组_mergeSort()函数所花的时间为 O(n);
公式:T[n] = 2T[n/2] + O(n);
所以得出的结果为:T[n] = O( nlogn )
归并排序虽然比较稳定,在时间上也是非常有效的(最差时间复杂度和最优时间复杂度都为 O(nlogn) ),但是这种算法很消耗空间,一般来说在内部排序不会用这种方法,而是用快速排序;外部排序才会考虑到使用这种方法;
3 函数增长率(ch3)
-
渐近记号 O、 Ω 、 θ 的定义及其使用
-
标准复杂性函数及其大小关系
-
和式界的证明方法
4 递归关系式(ch4)
-
替换法
(1)猜测解→数学归纳法证明;
(2)变量变换法; -
迭代法
(1)展开法:把递归式转化为求和表达式,然后求和式的界;
(2)递归树法:直观地表达了迭代法 -
主定理:给出了求解T(n) = aT(n/b)+f(n)这种形式递归式的简单方法。
对于:
通常得到三种情况:
上面三种case的快速记忆:
- 若函数 更大,如情况1,则 ;
- 若函数 更大,且满足 ,如情况3,则 ;
- 若两函数相等,则
以上的大小比价,都是渐进意义上的。
特别注意:对于形如[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XxTnCHNs-1599570079874)(C:\Users\Lenovo\Desktop\《算法基础》复习提纲.assets\image-20200908094511794.png)]
的式子,由于不属于多项式大,所以落入情况2、3之间,无法用主定理求解。
5 概率分析(ch5)
-
雇佣问题及其随机算法(略) -
序列随机排列的两种方法及其复杂性- 由随机数产生期生成数值,为每个元素 A[i] 分配一个随机数 P[i] 作为其优先权,然后依据这些优先权对数组A 进行排序。 (这种算法不是非常好)
- RANDOMIZE-IN-PLACE ,每次产生一个随机数,产生随机数的范围逐渐减小,逐次确定每一个数的位置。(这种算法更高明一些)
RANDOMIZE-IN-PLACE(A, n){
for(i=1; i<=n; i++)
swap(A[i], A[RANDOM(i, n)];
}
在线雇佣问题及其概率分析(略)
6 堆排序(ch6)
-
堆的概念和存储结构
-
堆的性质和种类
-
堆的操作:建堆;整堆;
MAX-HEAPIFY作用于一个高度为h的结点所需的运行时间为Θ(h)
BUILD-MAX-HEAP可以在线性时间内,将一个无序数组建成一个最大堆
-
堆排序算法和时间复杂性
-
优先队列及其维护操作
优先级队列是一种用来维护由一组元素构成的集合S的数据结构,这一组元素中的每一个都有一个关键字Key。
一个最大优先级队列支持以下操作:
① INSERT(S, x):把元素x插入集合S中;
② MAXIMUM(S):返回S中具有最大关键字的元素;
③ EXTRACT-MAX(S):去掉并返回S中的具有最大关键字的元素;
④ INCREASE-KEY(S, x, k):将元素x的关键字的值增加到k,这里k值不能小于x的原始关键字的值。
7 快速排序(ch7)
-
快速排序算法及其最好、 最坏时间和平均时间
-
随机快速排序算法及其期望时间
8 线性时间排序(ch8)
-
基于比较的排序算法下界: Ω (nlogn)
-
计数排序适应的排序对象、算法和时间
-
**基数排序**适应的排序对象、算法和时间
-
桶排序适应的排序对象、算法和时间
9 中位数和顺序统计(ch9)
(必看内容)
-
最大和最小值的求解方法
-
期望时间为线性的选择算法
-
最坏时间为线性的选择算法及其时间分析
10 红黑树(ch13)
- 红黑树的定义和节点结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T3opLGNv-1599570079875)(C:\Users\Lenovo\Desktop\《算法基础》复习提纲.assets\红黑树.png)]
-
黑高概念
-
一棵 n 个内点的红黑树的高度至多是 2log(n+1)
-
左旋算法
-
插入算法、时间、至多使用 2 次旋转 -
删除算法、时间、至多使用 3 次旋转
11 数据结构的扩张(ch14)
只用看一些习题即可
1.动态顺序统计:
扩展红黑树,支持①选择问题(给定 Rank 求相应的元素),②Rank 问题(求元
素 x 在集合中的 Rank)
(1)节点结构的扩展;
(2)选择问题的算法;
(3) Rank 问题的算法;
(4)维护树的成本分析;
2.如何扩张一个数据结构:扩张的步骤;扩张红黑树的定理(略);
3.区间树的扩张和查找算法(略)
12 递归与分治法(sch1)
需要重点理解一下。
-
递归设计技术
-
递归程序的非递归化
-
递归算法设计:
- 阶乘函数
生成n个元素的全排列- 将整数n划分成一系列正整数之和
最近点对大整数乘法Stranssen 矩阵乘法;~~
递归小结:
优点: 结构清晰,可读性强,而且容易用数学归纳法来证明算法的正确性,因此它为设计算法、调试程序带来很大方便。
缺点: 递归算法的运行效率较低,无论是耗费的计算时间还是占用的存储空间都比非递归算法要多。解决方法: 在递归算法中消除递归调用,使其转化为非递归算法。
1、采用一个用户定义的栈来模拟系统的递归调用工作栈。该方法通用性强,但本质上还是递归,只不过人工做了本来由编译器做的事情,优化效果不明显。
2、用递推来实现递归函数。
3、通过变换能将一些递归转化为尾递归,从而迭代求出结果。
后两种方法在时空复杂度上均有较大改善,但其适用范围有限。
- 分治法的使用条件:
- 该问题的规模缩小到一定的程度就可以容易地解决;
- 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质
- 利用该问题分解出的子问题的解可以合并为该问题的解;
- 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
人们从大量实践中发现,在用分治法设计算法时,最好使子问题的规模大致相同。即将一个问题分成大小相等的k个子问题的处理方法是行之有效的。这种使子问题规模大致相等的做法是出自一种平衡(balancing)子问题的思想,它几乎总是比子问题规模不等的做法要好。
13 动态规划(ch15)
-
方法的基本思想和基本步骤
-
动态规划和分治法求解问题的区别
-
最优性原理及其问题满足最优性原理的证明方法
- 算法设计
(1) 多段图规划;(2) 矩阵链乘法;
(3) 最大子段和;(4) 最长公共子序列;
(5) 0-1 问题求解;(6) 凸多边形最优三角剖分问题;
- 算法设计
14 贪心算法(ch16)
当一个问题具有最优子结构性质时,可用动态规划法求解,但有时用贪心算法求解会更加的简单有效。
-
方法的基本思想和基本步骤
-
贪心算法的正确性保证:满足贪心选择性质
在贪心算法(greedy method)中采用逐步构造最优解的方法。在每个阶段,都作出一个按某个评价函数最优的决策,该最优评价函数称为贪心准则(greedy criterion)。
- 贪心算法与动态规划的比较
动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。
-
两种背包问题的最优性分析:最优子结构性质和贪心选择性质
-
算法设计
(1)小数背包;(按照性价比装背包)
(2) 活动安排;(优先安排下最早结束的活动)
(3)找钱问题; (找钱时面额大的)
(4) 最优装载问题;(优先装轻的)
(5)单源最短路径;(Dijkstra算法)
(6)最小生成树;(Prim算法和Kruskal算法 )
注意0-1背包问题无法用贪心算法解决
15 回溯法(sch2)
-
方法的基本思想和基本步骤
-
回溯法是一种深度遍历的搜索
-
术语: 三种搜索空间, 活结点, 死结点, 扩展结点, 开始结点, 终端结点
基本思想:
— 搜索从开始结点(根结点)出发,以深度优先搜索整个解空间。
— 这个开始结点成为活结点,同时也成为当前的扩展结点。在当前的扩展结点处,搜索向纵深方向移至一个新结点。这个新结点就成为新的活结点,并成为当前扩展结点。
— 如果在当前的扩展结点处不能再向纵深方向扩展,则当前扩展结点就成为死结点。
— 此时,应往回移动(回溯)至最近的一个活结点处,并使这个活结点成为当前的扩展结点;直到找到一个解或全部解。
-
两种解空间树和相应的算法框架
-
算法设计:
(1) n 后问题;(2) 0-1 背包;
(3) 排列生成问题;(4) TSP 问题;(5) 符号三角形问题; (6) 图的 m 着色问题;
16 分支限界法(sch3)
-
方法的基本思想和基本步骤
-
与回溯法的区别
回溯法使用深度优先方法搜索,而分支限界一般用宽度优先或最佳优先方法来搜索;
- 活结点的两种扩展方式
分支限界法中,每一个活结点只有一次机会成为扩展结点。活结点一旦成为扩展结点,就一次性产生其所有儿子结点;
队列式(FIFO)分支限界法:从活结点表中取出结点的顺序与加入结点的顺序相同,因此活结点表的性质与队列相同;
优先队列(代价最小或效益最大)分支限界法:每个结点都有一个对应的耗费或收益,以此决定结点的优先级:
— 如果查找一个具有最小耗费的解,则活结点可用小根堆来建立,下
一个扩展结点就是具有最小耗费的活结点;
— 如果希望搜索一个具有最大收益的解,则可用大根堆来构造活结点
表,下一个扩展结点是具有最大收益的活结点。
-
0-1 背包问题的搜索: FIFO 队列和优先队列
-
算法设计
(1)0-1 背包问题;(2)装载问题(略);
(3)单源最短路径问题;
17 随机算法(sch4)
-
随机算法的定义
-
线性同余法是产生伪随机数的最常用的方法
-
随机算法的分类: 数值随机化算法、 拉斯维加斯算法、蒙特卡罗算法、舍伍德算法
(1)数值随机化算法:利用随机投点法求解π 值、计算定积分;(2)学过的舍伍德算法包括:快排的随机化版本、选择问题的随机化版本;
(3) N-后问题的拉斯维加斯算法,及其与回溯法的结合;
(4) 主元素问题的蒙特卡罗算法;
附:排序算法的复杂度及稳定性