算法导论 改进快排(1)----几乎有序的序列 7.4-5

来源:互联网 发布:vb中的标准模块是什么 编辑:程序博客网 时间:2024/05/10 09:40

问题:当输入数据已经“几乎有序”时,插入排序性能比快速排列好。为了提高快排速度,当对一个长度小于k的字数组调用快排时,让它不做任何排序就返回。当上层的快速排序调用返回时,对整个数组运行插入排序来完成排序过程。证明这一排序算法的期望时间复杂度为O(nk+nlg(n/k))

证明:严格的证明 http://m.blog.csdn.net/blog/leolinsheng/8915864, 我看了觉得也不是很严谨,不等式放缩那块感觉不是太对

           宽松的证明思路: 快排----递归树     以T(n)=T(an)+T((1-a)n)+cn (0.5<a<1)为例, 分解直至长度等于k,(a^h)n =k, h=loga(k/n)=O(lg(n/k))(a<1), 每层计算量为cn, 总和为                                                                           O(nlg(n/k))

           插入排序              共n/k个子序列,每个子序列复杂度为O(k^2),   总和为O(nk)

                                          总时间复杂度为O(nk+nlg(n/k))

代码实现这一改进:  

 

#include<iostream>#include<stdlib.h>#include<time.h>using namespace std;#define K 6//交换两个数void Swap(int & a, int &b){int temp=b;b=a;a=temp;}//使用随机化版本的快排int R_Partition(int *A, int p, int r){int i=rand() % (r-p+1)+ p; //产生[p,r]之间的随机整数Swap(A[i],A[r]);    int l=p-1;for(int j=p;j<=r-1;j++){if(A[j]<=A[r]){++l;Swap(A[l],A[j]);}}Swap(A[l+1],A[r]);return l+1;}void R_QuickSort(int *A, int p, int r){if(r-p+1>=K){int q=R_Partition(A,p,r);R_QuickSort(A,p,q-1);R_QuickSort(A,q+1,r);}}//插入排序void InsertSort(int *A, int p, int r){for(int m=p+1;m<=r;m++){int n=m-1;int temp=A[m];while(n>=p && A[n]>temp){    A[n+1]=A[n];--n;}A[n+1]=temp;}}void Sort(int *A, int p, int r){R_QuickSort(A, p, r);InsertSort(A,p,r);}int main(){int A[9]={2,4,1,6,4,5,9,3,7};for(int i=0;i<9;i++){cout<<A[i]<<" ";}cout<<endl;srand((unsigned)time(NULL)); Sort(A,0,8);for(int j=0;j<9;j++){cout<<A[j]<<" ";}return 0;}


0 0
原创粉丝点击