递归与分治策略
【Master定理】
主定理【Master定理】提供了分治方法带来的递归表达式的渐进复杂度分析。
将规模为 n 的问题通过分治,得到 a 个规模为 n/b 的问题,每次递归带来的额外计算为 c ( n d ) c(n^d) c(nd)
即 T ( n ) = a ( n / b ) + c ( n d ) T(n)=a(n/b)+c(nd) T(n)=a(n/b)+c(nd)
- 若 a = b d , T ( n ) = O ( n d l o g ( n ) ) a=bd , T(n)=O(ndlog(n)) a=bd,T(n)=O(ndlog(n))
- 若 a < b d , T ( n ) = O ( n d ) a<bd , T(n)=O(nd) a<bd,T(n)=O(nd)
- 若 a > b d , T ( n ) = O ( n l o g b ( a ) ) a>bd , T(n)=O(nlogb(a)) a>bd,T(n)=O(nlogb(a))
快速排序
快速排序算法是基于分治策略的另一个排序算法。其基本思想是,对于输入的子数组a【p:r】,按以下三个步骤进行排序。
①分解(Divide) :以a【p】为基准元素将a【p : 】划分成3段a 【p : q-1) ,a 【g】和a【g+1 :r】,使ap : q-1】中任何一个元素小于等于a 【g】,而a【q+1:】中任何一个元素大于等于a【g】 】。下标q在划分过程中确定。
②递归求解(Conquer):通过递归调用快速排序算法,分别对a 【p : q-1】和a【g+1:】进行排序。
③合并(Merge):由于对a 【p: q-1】和a【g+1 : r】的排序是就地进行的,因此在a【p: g-1】和a 【g+1 :r】都已排好的序后,不需要执行任何计算,a【p: r】则已排好序。
基于这个思想,可实现快速排序算法如下:
根据基本思路,得到以下代码:
对应的题目【模板】快速排序
代码:
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1E5 + 10;
int n , a[N];
int Partition(int a[] , int p ,int r){
int i = p , j = r + 1 ;
int x = a[p];
while(true){
while(a[++i] < x && i < r ); // 我们向右拓展,直到找到一个比 x 大或者等于的
while(a[--j] > x ); // 我们向左延伸,直到遇到一个 <= x 的数
if(i >= j)break; // 因为有不等式 a[i] >= x >= a[j] ,也就是最终i应该在x 右边,j在其左边
swap(a[i],a[j]); // 但 j 如果在右边,i在左边,则交换
}
a[p] = a[j] , a[j] = x; // j为划分点
return j;
}
void qsort(int a[] , int p , int r){
if(p < r){
int q = Partition(a , p ,r); // 分解,分为以 a[q]为界限分为三段
qsort(a , p ,q - 1); // 对左半段排序
qsort(a , q + 1 ,r); // 对右半段排序
}
}
int main(){
cin>>n;
for(int i = 1 ; i <= n ; ++i)cin>>a[i];
qsort(a , 1 , n);
for(int i = 1 ; i <= n ; ++i)cout<<a[i]<<" ";
return 0;
}
快速排序的运行时间与划分是否对称有关,其最坏情况发生在划分过程产生的两个区域分别包含n-1个元素和1个元素的时候。由于函数Partition)的计算时间为O(n),所以如果算法Partition的每步都出现这种不对称划分,则其计算时间复杂性T(n)满足
T ( n ) = { O ( 1 ) n < = 1 T ( n − 1 ) O ( n ) x > 1 T(n) = \begin{cases} O(1) & n <= 1 \\ T(n-1) O(n) & x >1 \\ \end{cases} T(n)={
O(1)T(n−1)O(n)n<=1x>1
我们可以通过递归子树来求解。如下图

这很明显是一个等差数列,我们利用求和公式很容易解出,此递归方程,可得 T ( n ) = O ( n 2 ) T(n) = O(n^2) T(n)=O(n2)。
在最好情况下,每次划分所取的基准都恰好为中值,即每次划分都产生两个大小为n/2的区域,此时,Partition算法的计算时间T(n)满足
T ( n ) = { O ( 1 ) n < = 1 2 T ( n / 2 ) + O ( n ) x > 1 T(n) = \begin{cases} O(1) & n <= 1 \\ 2T(n/2) + O(n) & x >1 \\ \end{cases} T(n)={
O(1)

本文探讨了递归与分治策略在算法中的应用,重点讲解了Master定理在快速排序优化中的运用,包括快速排序的基本原理、最优情况与最坏情况下的时间复杂度分析,以及如何通过随机化改进快速排序。此外,文中还涉及逆序对的归并算法、火柴排队问题、集合求和的组合数学方法以及一些经典问题如越狱、平面上的最接近点对和棋盘覆盖的解决方案。
最低0.47元/天 解锁文章
1032

被折叠的 条评论
为什么被折叠?



