第七章快速排序之“快速插入排序”(练习7.4-5)
2012-01-05 22:03
309 查看
O(∩_∩)O~,这个名字乍听起来比较黄。其实就是先快速排序进行划分,等划分小到一定规模比如k时,进行插入排序,因为规模小到一定程度,插入排序的效率更高。我在前面还写过一个合并插入排序的算法,思想跟这个相似。
总的时间复杂度为O(nk+nlg(n/k)),这个很好证明:
先进行二分,划分到规模都为K时停止划分,此时深度为h,则T(n/2^h)=k,则h=lg(n/k),最底层规模为K的叶节点数目为2^lg(n/k)=n/k,每个k内部插入排序,最坏情况为O(k^2),则总的插入排序时间为(n/k)*(k^2)=nk。每一层的划分耗费为n,一共需划分lg(n/k)层,耗费为O(nlg(n/k))。则总的时间复杂度是两者相加共O(nk+nlg(n/k))。
代码如下:
总的时间复杂度为O(nk+nlg(n/k)),这个很好证明:
先进行二分,划分到规模都为K时停止划分,此时深度为h,则T(n/2^h)=k,则h=lg(n/k),最底层规模为K的叶节点数目为2^lg(n/k)=n/k,每个k内部插入排序,最坏情况为O(k^2),则总的插入排序时间为(n/k)*(k^2)=nk。每一层的划分耗费为n,一共需划分lg(n/k)层,耗费为O(nlg(n/k))。则总的时间复杂度是两者相加共O(nk+nlg(n/k))。
代码如下:
#include <string.h> #include <time.h> #define BUFFER_SIZE 10 int Partition(int *a,int p,int r) { int i=0; int j=0; int tmp=0; int x=0; i=p-1; x=a[r]; for(j=p;j<r;j++) { if(a[j]<=x) { i++; tmp=a[i]; a[i]=a[j]; a[j]=tmp; } } tmp=a[i+1]; a[i+1]=a[r]; a[r]=tmp; return i+1; } int RandomPartition(int *a,int p,int r) { int i=0; int tmp=0; srand((unsigned)time(NULL)); i=rand()%(r-p+1)+p; tmp=a[i]; a[i]=a[r]; a[r]=tmp; return Partition(a,p,r); } void InsertionSort(int *a,int p,int r) { int n=r-p+1; int b ; int i=0; int j=0; b[0]=a[p]; for(j=p+1;j<=r;j++) { i=j-1; while(i>=0&&a[j]<=b[i]) { b[i+1]=b[i]; i--; } b[i+1]=a[j]; } for(j=p,i=0;j<=r;j++) { a[j]=b[i]; i++; } } void RandomQuickSort(int *a,int p,int r,int k) { int q=0; if(p>=r) { return; } if(r-p+1<k) { InsertionSort(a,p,r); } else { q=RandomPartition(a,p,r); RandomQuickSort(a,p,q-1,k); RandomQuickSort(a,q+1,r,k); } } int main() { int i=0; int j=0; int a[BUFFER_SIZE]; //随机生成数组 srand((unsigned)time(NULL)); for(j=0;j<BUFFER_SIZE;j++) { a[j]=rand()%100; } printf("随机生成的数组:\n"); for(i=0;i<BUFFER_SIZE;i++) { printf("%d ",a[i]); } printf("\n"); RandomQuickSort(a,0,BUFFER_SIZE-1,1); printf("对数组进行快速插入排序:\n"); for(i=0;i<BUFFER_SIZE;i++) { printf("%d ",a[i]); } system("pause"); return 0; }
相关文章推荐
- 练习《算法导论》之排序:插入排序,归并排序,堆排序,快速排序
- 冒泡排序 快速排序 选择排序 堆排序 直接插入排序 希尔排序 归并排序
- 插入排序 冒泡 选择 快速
- java---插入排序,冒泡,归并,快速,希尔,堆排序
- 插入排序、冒泡排序、选择排序、希尔排序、快速排序、归并排序、堆排序和LST基数排序——JAVA实现
- 【更新】排序算法比较:插入排序,冒泡排序,归并排序,堆排序,快速排序,计数排序,基数排序,桶排序
- 第七章快速排序之“采取“尾递归”和“三数取中”技术的快速排序”(思考题7-4、7-5)
- 排序——冒泡、归并、快速、选择、插入、堆
- [算法练习]插入排序的C语言实现
- 快速排序练习(二)
- IOS- 快速排序,冒泡排序,直接插入排序和折半插入排序,希尔排序,堆排序,直接选择排序
- 排序总结:插入(简单和改进)、希尔、选择、冒泡、快速、堆排序、归并排序
- 冒泡,插入,折半插入,希尔,快速,简单选择排序源码总结
- 插入,冒泡,选择,快速排序,二分查找(Java版)
- 八大排序方法汇总(选择排序,插入排序-简单插入排序、shell排序,交换排序-冒泡排序、快速排序、堆排序,归并排序,计数排序)
- 插入排序、快速排序、堆排序
- 随机生成30个数,试比较直接插入排序、简单选择排序、冒泡排序、快速排序、堆排序和希尔排序的时空性能和稳定性。
- 排序(冒泡、选择、插入、快速)
- java 数组的排序,含冒泡、插入、选择、快速排序。
- Scala练习-直接插入排序