归并排序

来源:互联网 发布:金蝶软件财务报表 编辑:程序博客网 时间:2024/06/01 10:39

首先对归并进行了解:

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并

归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]

以上内容摘自360百科,下面举一个例子表达我对归并的理解。

一个数列:{13, 27, 19, 8, 12, 2,  30, 89}

第一次排序:{13 ,27} ,{19 , 8}, {12 , 2}, {30 ,89}

排序后 {13,27} ,{8, 19},{2,12},{30,89}                

            13,27,8,19,2,12,30,89                 

第二次排序:{13,27,8,19} ,{2,12,30,89}

排序后:{8,19,13,27},{2,12,30,89}       

              8 , 9, 13,27,2,12,30,89         

第三次排序{8 , 9, 13,27,2,12,30,89}

排序后:2,8,9,12,13,27,30,89         

代码分析:

int Mergesort(int a[],int s,int e,int tmp[])
{
if(s < e)
{
int m = s+ (e-s)/2;  
Mergesort(a,s,m,tmp);  //对左区间归并
Mergesort(a,m+1,e,tmp); // 对右区间归并
Merge(a,s,m,e,tmp); //对数组a 区间 a[s] 到 a[e] 排序 
}

}

立即上面的代码,可以参考上面的例子, 理解这段代码,需要理解递归知识,递归实现是先进后出(栈存储)。

如果用这段代码对上面的数列 {13, 27, 19, 8, 12, 2,  30, 89}进行排序:

进栈:

第一个进栈是: 第三步 -->  第二个进栈是: 第二步 --> 第三个进栈是: 第一步

出栈(执行,进行排序):

第一个出栈是: 第一步 -->  第二个进栈是: 第二步 --> 第三个进栈是: 第三步

过程就像上面对数列模拟的样子                                                                       

给出代码:

#include <stdio.h>int Merge(int a[],int s,int m,int e,int tem[]) //对数组a 区间 a[s] 到 a[e] 排序 {    int p1 = s, p2 = m+1;int pb = 0;while(p1 <= m && p2 <= e){if(a[p1] < a[p2])tem[pb++] = a[p1++];elsetem[pb++] = a[p2++];}while(p1 <= m){tem[pb++] = a[p1++];}while(p2 <= e){    tem[pb++] = a[p2++];} for(int i=0; i<e-s+1; i++) a[s+i] = tem[i];}int Mergesort(int a[],int s,int e,int tmp[]){if(s < e){int m = s+ (e-s)/2;  Mergesort(a,s,m,tmp);  //对左区间归并Mergesort(a,m+1,e,tmp); // 对右区间归并Merge(a,s,m,e,tmp); //对数组a 区间 a[s] 到 a[e] 排序 }}int a[8] = {13, 27, 19, 12, 2, 8, 30, 89}; // 样例数列 int b[10]; // 中间变量数组,无实际意义。 int main(){int size = sizeof(a)/sizeof(int);Mergesort(a,0,size-1,b); // 对 a[] 归并排序 for(int i=0;i<size;++i)   printf("%d ,",a[i]);  // 输出数组 a   return 0;} 


      如有错误,请指出。

原创粉丝点击