归并排序,在直接手动操作排序时:
先将待排序的序列按序两个1合成一个2,两两一组,如果最后剩下一个单独的,则它自己独为一组,组内两数据比较排序;
再将两个2合成一个4,继续在组内排序,不够两组2的单独为组,不用进行排序了;
这样下去,知道最后将所有数合成一组,最后排序一次得到有序序列;
这里在对两个x合成一个2x时,使用的方法是我们常见的,将两个有序数组合成一个有序数组的方法。这个方法合并两个数组的时间复杂度是两数组长度和。
合并两个有序数组并不难,但是归并排序需要的不仅仅是这个,这里使用递归的方法将数组一分为二,两边分别有序之后再使用上面合并有序数列的方法,把两边分别看成两个有序数列,进行合并;而两边的有序又分别需要对自己的归并排序,构成递归;
逻辑关系:
//merge_sort递归合并
void merge_sort(int a[],int start,int end)
{
int mid;
if(start<end)
{
mid=(start+end)/2;
merge_sort(a,start,mid);
merge_sort(a,mid+1,end);
MemerySort(a,start,mid,end);
}
}
MemerySort用于对两个有序数组合并,但这里鉴于归并排序的特定情况,它是要求对同一个数组的相邻两有序部分进行合并,因此MemerySort的参数设置是如上,
使start到mid部分为一个有序数列,mid+1到end部分为另一个有序数列,在函数体中使用一个数组存放合并后的结果,最后再赋给数列a的start到end部分,以此实现合并;
//MemerySort合并两个有序序列,并将结果存在参数数列中
void MemerySort(int a[],int start,int mid,int end)
{
int c[10],i=start,j=mid+1,k=0;
while(i<=mid&&j<=end)
{
if(a[i]<=a[j])
c[k++]=a[i++];
else c[k++]=a[j++];
}
while(i<=mid)
c[k++]=a[i++];
while(j<=end)
c[k++]=a[j++];
for(i=0;i<k;i++)
a[i+start]=c[i];
}
完整代码:
/******************************************
*Date:2014.02.04
*Function:将两个有序数列
* 合成一个有序数列
******************************************/
#include<stdio.h>
//MemerySort合并两个有序序列,并将结果存在参数数列中
void MemerySort(int a[],int start,int mid,int end)
{
int c[10],i=start,j=mid+1,k=0;
while(i<=mid&&j<=end)
{
if(a[i]<=a[j])
c[k++]=a[i++];
else c[k++]=a[j++];
}
while(i<=mid)
c[k++]=a[i++];
while(j<=end)
c[k++]=a[j++];
for(i=0;i<k;i++)
a[i+start]=c[i];
}
//merge_sort递归合并
void merge_sort(int a[],int start,int end)
{
int mid;
if(start<end)
{
mid=(start+end)/2;
merge_sort(a,start,mid);
merge_sort(a,mid+1,end);
MemerySort(a,start,mid,end);
}
}
int main()
{
int a[10];
for(int i=0;i<10;i++)
scanf("%d",&a[i]);
merge_sort(a,0,9);
for(i=0;i<10;i++)
printf("%d ",a[i]);
return 0;
}