算法导论 2-1思考题 合并排序中对小数组采用插入排序
来源:互联网 发布:手机直播源码 编辑:程序博客网 时间:2024/05/29 15:50
在合并排序中对小数组采用插入排序。
注:书里的那个O里还有一杠的符号打不出来,所以这里用大O代替了,特指同阶无穷大量。
尽管合并排序最坏情况运行时间为O(nlgn),插入排序的最坏运行时间为O(n^2),但是插入排序的常数因子使得它在n较小时,运行要更快一些。因此,在合并排序算法中,当子问题足够小时,采用插入排序就比较合适了。考虑对合并排序做这样的修改,即采用插入排序策略,对n/k 个长度为 k 的子列表进行排序。然后,再用标准的合并机制将它们合并起来,此处k是一个待定的值。
a) 证明在最坏的情况下,n/k个子列表可以用插入排序在O(nk)的时间内完成排序
b) 证明这些子列表可以在O(nlg(n/k))最坏情况内完成合并。
c) 如果已知修改后的合并排序算法的最坏运行时间为O(nk+nlg(n/k)),要使得修改后的算法具有与标准合并算法一样的渐进运行时间,k的最大渐进值( 即O形式)是什么(以n的函数形式表示)?
注:书里的那个O里还有一杠的符号打不出来,所以这里用大O代替了,特指同阶无穷大量。
尽管合并排序最坏情况运行时间为O(nlgn),插入排序的最坏运行时间为O(n^2),但是插入排序的常数因子使得它在n较小时,运行要更快一些。因此,在合并排序算法中,当子问题足够小时,采用插入排序就比较合适了。考虑对合并排序做这样的修改,即采用插入排序策略,对n/k 个长度为 k 的子列表进行排序。然后,再用标准的合并机制将它们合并起来,此处k是一个待定的值。
a) 证明在最坏的情况下,n/k个子列表可以用插入排序在O(nk)的时间内完成排序
b) 证明这些子列表可以在O(nlg(n/k))最坏情况内完成合并。
c) 如果已知修改后的合并排序算法的最坏运行时间为O(nk+nlg(n/k)),要使得修改后的算法具有与标准合并算法一样的渐进运行时间,k的最大渐进值( 即O形式)是什么(以n的函数形式表示)?
d) 实践中,应该如何选取k值。
参考答案:
a、O(n/k*k^2)=O(nk).这里的O中间有一横
b、n/k个列表两两合并,合并完继续合并,共lg(n/k)对,合并的代价O(n).所以O(nlg(n/k)).
c、O(nk+nlg(n/k))=O(nlgn).只能最大是k=O(lgn).等式左边中第一项是高阶项。k如果大于lgn,则比归并排序复杂度大了。左边可以写成nk+nlgn-nlgk,k等于lgn时,就是2nlgn-nlglgn.忽略恒定系数,则与归并排序是一样的。
b、 实践中,k的值应该选为使得插入排序比合并排序快的最大的数组长度。很容易理解,假设k=1,那么退化为标准合并排序,那么要提高效率需放大k,k放大到使得array[k]使用插入排序比合并排序快,而array[k+1]的插入排序效率不如或等于合并排序。
#include <stdio.h> #include <string.h> #include <time.h> #define BUFFER_SIZE 10 int InsertionSort(int *a,int p,int q) { int i=0; int j=0; int b[q-p+1]; memset(b,0,sizeof(b)); b[0]=a[p]; for(i=p+1;i<=q;i++) { j=i-p-1; while(j>=0&&b[j]>=a[i]) { b[j+1]=b[j]; j--; } b[j+1]=a[i]; } for(i=p,j=0;i<=q;i++) { a[i]=b[j]; j++; } } void Merge(int *a,int p,int q,int r) { int n1=q-p+1; int n2=r-q; int i=0; int j=0; int k=0; int b[n1+1]; int c[n2+1]; memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); b[n1]=BUFFER_SIZE;//设置哨兵元素,注意不要溢出 c[n2]=BUFFER_SIZE;//设置哨兵元素,注意不要溢出 for(i=0;i<n1;i++) { b[i]=a[p+i]; } for(i=0;i<n2;i++) { c[i]=a[q+1+i]; } for(i=p,j=0,k=0;i<=r;i++) { if(b[j]<=c[k]) { a[i]=b[j]; j++; } else { a[i]=c[k]; k++; } } } void MergeAndInsertionSort(int *a,int p,int r,int k) { int q=0; if(p>=r) { return; } q=(p+r)/2; if((q-p+1)<=k)//子数组长度≤k的时候就不再进行划分,而是对该子数组进行插入排序 { InsertionSort(a,p,q); } else { MergeAndInsertionSort(a,p,q,k); } if(r-q<=k) { InsertionSort(a,q+1,r); } else { MergeAndInsertionSort(a,q+1,r,k); } Merge(a,p,q,r); } void Output(int *a,int len) { int i=0; for(i=0;i<len;i++) { printf("%d ",a[i]); } printf("\n"); } int main() { int i=0; int k=1; int a[BUFFER_SIZE]; memset(a,0,sizeof(a)); srand((unsigned)time(NULL)); for(i=0;i<BUFFER_SIZE;i++) { a[i]=rand()%BUFFER_SIZE; } printf("随机生成的数组:"); Output(a,BUFFER_SIZE); k=rand()%BUFFER_SIZE+1; printf("k=%d\n",k); MergeAndInsertionSort(a,0,BUFFER_SIZE-1,k); printf("排序后的数组:"); Output(a,BUFFER_SIZE); system("pause"); return 0; }
0 0
- 算法导论 2-1思考题 合并排序中对小数组采用插入排序
- 第二章之“合并排序中对小数组采用插入排序”(思考题2-1)
- 合并排序中对小数组采用插入排序
- 归并排序中对小数组采用插入排序
- 算法导论 思考题7_2 对区间的模糊排序
- 算法导论1插入排序
- 《算法导论》(一)--插入排序与合并排序
- 算法导论学习之插入排序+合并排序
- 算法导论 8-2思考题 之线性时间原址排序
- 算法导论CLRS 7 思考题 Stooge排序
- 算法导论第六章堆排序思考题
- 改进的合并排序算法(小数组内使用插入排序算法)
- 算法导论 第2章 算法入门(直接插入排序、希尔排序、冒泡排序、合并排序)
- 算法导论:插入排序
- 插入排序【算法导论】
- 算法导论-----插入排序
- 算法导论-插入排序
- 《算法导论》 插入排序
- centos 无线网卡配置
- echo 命令
- Ch4-1: identify if a tree is "balanced" (注:CTCI 第四版和第五版的定义不一样)
- 各种桑心哇
- scanf的用法
- 算法导论 2-1思考题 合并排序中对小数组采用插入排序
- windows 8.1使用Android模拟器并用intel HAXM加速导致蓝屏
- 黑马程序员_Date
- 成熟男人的标准 你达到几条
- 认识JavaScript中的作用域和上下文
- Maximum Subarray
- 除了陆展博和关谷,其他人の收入,一辈子在上海也只能蜗居吧?
- 第5天 反转链表
- .Net Framework CLR 托管程序执行机制