归并排序算法论文

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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);

相关文档
最新文档