.....
如例 1:使用 $W(n-1)= W(n-2)+n-1$来替换 $W(n-1)$
主定理:设 $T(n)$ 是一个非递归函数,并且满足递推式 $$ T(n)=\alpha T(n/b)+f(n), 其中 n=b^k,k=1,2,...... $$
$$ T(1)=c $$
其中 $a \geqslant 1, b \geqslant 2, c > 0$如果 $f(n) \in \theta (n^d), d \geqslant 0$,那么
- 当 $a<b^d$ 时, $T(n) \in \theta (n^d)$
- 当 $a=b^d$ 时, $T(n) \in \theta (n^dlogn)$
- 当 $a>b^d$ 时, $T(n) \in \theta (n^{log_ba})$
算法利用一个规模为 n 的实例和规模为 n-1 的给定实例之间的关系来对问题求解(插入排序)
$$ T(n)=T(n-1)+f(n) $$
规模为 n 的实例化简为一个规模为 $n/b$ 的给定实例来求解(折半查找)
$$ T(n)=T(n/b)+f(n) $$
给定实例划分为若干个较小的实例,对每个实例递归求解,然后再把较小的实例合并成给定实例的一个解(快速排序,合并排序)
$$ T(n) = T(n/b) + f(n) $$
假设有 A,B,C 三根柱子,在 A 柱上放着 n 个圆盘,其中小圆盘放在大圆盘的上面。我们的目的是从 A 柱将这些圆盘移动到 C 柱上去,在必要的时候可借助 B 柱,每次只能移动一个盘子,并且不允许大盘子在小盘子上面。问需要多少次的移动?
解决办法
$$ 递推关系 M(n)=\left{\begin{matrix} 2M(n-1)+1, & n>1 & \ 1, & n=1 & \end{matrix}\right. $$
- 将问题划分为同一类型的若干子问题,子问题最好规模相同;
- 对这些子问题求解(通常使用递归的方式);
- 合并这些子问题的解,以得到原问题的解;
可以使用主定理对分治法的复杂度进行分析
不一定所有的问题分治就一定比蛮力好,只是往往比其好,所以就需要我们进行算法效率的分析了
TODO
算法效率分析
基本操作为元素之间的比较
比较次数的递推关系: $$ C(n)=2C(n/2)+C_{merge}(n),C(0)=1,其中 n=2^k $$
最坏情况下, $C_{merge}(n)=n-1$;
最坏情况下效率: $$ C_{worst}(n)= \left{\begin{matrix} 2C_{worst}(n/2)+n-1 & n>1\ 0 & n=1 \end{matrix}\right. $$
根据主定理可得$C_{worst}(n)=\theta (nlogn)$
合并排序在最坏情况下的比较次数十分接近基于比较的排序算法的理论上能够达到的最少比较次数
合并排序的主要缺点是需要线性的额外空间
合并排序按照元素的位置划分并合并的方式进行排序。划分过程很快,主要工作在合并子问题。子问题递归排序后,合并很简单(拼接),主要工作在如何划分(如何有效地划分?),这就是快速排序算法。
更好地理解快速排序
选择排序的一种,每次选择大根堆(小根堆)的堆顶,然后放入有序区(堆底)
- 建堆
- 删除最大键
算法效率分析
第一阶段(构造堆--自底向上)复杂度为$O(n)$;
第二阶段(删除最大键)键值比较次数: $$ C(n) \leq 2log_2(n-1)+2log_2(n-2)+...+2log_21 \leq 2nlog_2n $$
总的效率为$O(nlogn)$(任何情况),且无需额外的存储空间
对于随机的输入,堆排序比快速排序运行的慢
无序区向有序区依次扫描插入
算法 | 最好效率 | 最差效率 | 平均效率 |
---|---|---|---|
选择排序 | $n^2$ | $n^2$ | $n^2$ |
冒泡排序 | $n^2$ | $n^2$ | $n^2$ |
插入排序 | $n$ | $n^2$ | $n^2$ |
合并排序 | $nlogn$ | $nlogn$ | $nlogn$ |
快速排序 | $nlogn$ | $n^2$ | $nlogn$ |
堆排序 | $nlogn$ | $nlogn$ | $nlogn$ |
前面还有常数
分治法求解思路
实例:寻找 9 个数的中位数(k=5)
TODO
TODO
TODO
TODO