归并排序算法论文
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
归并排序算法解决排序问题
目录
1引言 (2)
2.归并排序的基本思想 (2)
3.归并排序算法不同的方式 (3)
1.归并排序基本算法 (3)
1.实现过程 (3)
2.性能分析: (4)
2.递归二路归并排序 (5)
1.算法过程 (5)
2.性能分析: (6)
3.归并排序算法的改进算法 (7)
1.引理 (7)
2.应用例子 (7)
3.时间复杂性的分析 (8)
4.总结 (9)
5.参考文献 (9)
1引言
从归并排序的概念上进行分析,该算法的思想比较容易理解,并且也能够直观的感知其实质是利用存储空间的归并。在实现的过程中,可以有多种方法,画出归并过程示意图后,随即可以得出其算法的代码。但是我们在利用递归思想实现归并排序的教学程中,一定要让学生分清是用递归还是用回归进行的归并,画出图形区分这两种不同的归并过程。通过这一环节,我们不但能够理解稳定的归并排序,而且还让学生认清递归和回归是解决这一问题两种不同的操作过程。
2.归并排序的基本思想
归并排序主要是二路归并排序,它的基本思想是:设n个数据,初始时把他们看成n 个长度为l的有序子数组,然后从第—个子数组开始,把相邻的子数组两两归并,得到n/2个长度为2的新的有序子数组(当n为奇数是最后—个新的有序子数组长度为1);对这些新的有序子数组再两两归并;如此重复,直到得到—个长度为n的有序数组为止”。归并排序有两种实现方法:自顶向下和自底向上,前者定义是自底向上,
3.归并排序算法不同的方式
1.归并排序基本算法
1.实现过程
当初次理解归并概念的时候,我们可以列举下列一组数据的归并过程。例如:70 83 100 65 10 32 7 65 9
第一次:【70 83】【65 100】【10 32】【7 65】【9】
第二次:【65 70 83 100】【7 10 32 65】【9】
第三次:【7 10 32 65 65 70 83 100】【9】
第四次:【7 9 10 32 65 65 70 83 100】
具体程序代码如下:
函数:void merge(int e[],int n)
形参说明:e是已知待排序的数组,n是数组中元素的个数,下标从0开始。void merge(int e[],int n)
{ int +p=(int+)malloc(Sizeof(int)+n);/*开辟一块实现交替归并空间*/
int len=l,f=0;/*len为归并单元宽度,f是一个标识,实现交替归并*/while(1en { if(f==0)merge pass(e,P,n,len);/*交替进行归并*/ else merge.pass(p,e,n,fen); len*=2;/*扩大归并单元宽度*/ f=l—f; } if(f) /*将最终结果存放的指定数据域中*/ for(f=0;f free(p); } Void merge_pass(int e[],int a[],int n,int len) { int f _S,s_end;/*f_ s存放即将归并的第一个单元起始下标*/ f _s=0;/*S_end存放即将归并的第二个单元末下标*/ while(f_s+ len { s_end2=f_s+2*len- 1; if(S end>=n)s end=n一1; /*确定真正末下标位置*/ merg_step(e,a,f_s,f_s+len-1,s_end);/*实现将两个单元合并*/ f_s=S_end+l; } if(f_s for(;f_s a[f_s]=e[f S]; } void merge step(int e[],int a[],int s,int m,int n) { /*实现将两部分单元归并,m为分界点下标,即为第一单元的末下标*/ int i,J,k;k=i=s;J=m+1; while(i<=m&&j<=n) if(e[i]<=e[j] a[k++]=e[i++]; else a[k++]=e[j++]; while(i<=m) a[k++]=e[i++]; while(j<=n) a[k++]=e[j++]; 2.性能分析: 利用最基本的方法实现归并排序,我们需要利用三个函数,在实现的过程中,程序的可读较高。但是在程序执行的过程中,函数之间需要频繁的进行嵌套调用,数据的交替归并也显得比较麻烦,所以在正确的实现归并算法的基础上,我们引入了递归序列的方法。 2.递归二路归并排序 1.算法过程 利用递归的思想可以掩盖上一方法的频繁嵌套调用,而利用递归的真正目的还可以解决上一方法中数据的交替归并,其方法是它将数组分解成两部分a[1],⋯,a[m]和a[m+1],⋯,a[r]来排序数组a [l],⋯,a[r]。这两个子数组部分独立排序(通过递归调用),而且将生成的有序予文件归并得到最后的所有文件。进而可以得到一个原形化的分治递归程序。在分解过程中我们可以参照下面的数据分解图。例如:一组数据为:70、83、100、65、10、32、7、65、9共9个元素,由元素的个数我们可以画出二分递归图形。 令函数内部第一次递归调用左半部分,可以得出归并的过程: [70 83] 100 65 10 32 7 65 9 [70 83 100] 65 10 32 7 65 9 [70 83 100] [10 65]32 7 65 9 [10 65 70 83 100] 32 7 65 9 [10 65 70 83 100] [7 32] 65 9 [10 65 70 83 100] [7 32] [9 65] [10 65 70 83 100] [7 9 32 65] [7 9 10 32 65 65 70 83 100] Void merge(int sr[],int tr[],int I,int m,int n) Int j2=m+1,j1=I,k=I; if(sr[j1]<=sr[j2])tr[k++]=st[j1++]; else tr[k++]=sr[j2++]; while(j1<=m) tr[k++]=sr[jl++]; while(j2<=n) tr[k++]=sr[J2++]; for(k=i;k<=n;k++) sr[k]=tr[k]; ) · Void msort(int sr[],int tr[],int S,int t) t int m; if(s==t) tr[s]=sr[S]; else (m=(s+t)/2; msort(sr,tr,s,m);