归并排序是将两个或两个以上有序子序列归并成一个有序数列的排序的排序算法,其时间复杂度O(n*log n)仅次于快速排序。在内排序中,通常采用的是2-路归并,即每两个子序列为一组进行排序。归并排序的原理是:设初始序列含有N个记录,则可以看成N个有序的子列,每个子序列的长度为1,然后两两归并,得到N/2个长度为2或1的子序列,再两两归并,如此重复的归并下去,直到到达一个有序的序列为止。
设初始数组为:49,38,65,97,76,13,27。则归并过程如下
归并排序的思想简要介绍如下:对2个有序的子数组,开辟一个大小为两数组长度的新数据,先比较两子数据的首元素,将小者存入新数组,同时新数组和存数的那个数组后移一位,继续比较,若某个数组的元素都比较完了,则将为比较完的数组的元素一次填入新数组。
归并排序最好,最坏及平均时间复杂度皆为O(n*log n),可见其效率是很高的,但是它的空间复杂度O(n),这也是用空间换时间的缘故,算法中,空间复杂度和时间复杂度是一对矛盾体,我们需要找出它们的平衡点,才能设计出高效的算法。归并排序也是高效排序算法中唯一稳定的算法(稳定性是指最坏情况下时间复杂度和最好情况下时间复杂度,若相同则稳定,若不同则不稳定)
归并排序多用于外排序中,这里的“外”是指外存,多数情况是硬盘,它可用于较大数据量的排序,通常将大数据量分割成若干个小数据量,然后用快速排序或其他算法对小数据量进行排序,,这几块小数据量排完序后,再对其归并排序,这样就对整个大数据量完成了排序。
归并排序参考代码如下:
//description:归并排序
//author:hust_luojun
//date:2014_7_23
#include <iostream>
using namespace std;
int main()
{
void merge_sort(int a[], int b[],int,int);
int a[]={3,6,18,25,28};
int b[]={4,8,12,20,26,30,56};
int length_a=sizeof(a)/sizeof(int); //求数组元素个数
int length_b=sizeof(b)/sizeof(int);
cout<<"arrary a:"<<endl;
for(int i=0;i<length_a;i++)
cout<<a[i]<<" ";
cout<<endl;
cout<<"arrary b:"<<endl;
for(int j=0;j<length_b;j++)
cout<<b[j]<<" ";
cout<<endl;
merge_sort(a,b,length_a,length_b);
return 0;
}
void merge_sort(int a[],int b[],int length_a,int length_b)
{
int length_c=length_a+length_b;
int c[length_c];
int i=0;
int j=0;
int k=0;
while(i<length_a&&j<length_b)
{
if(a[i]<=b[j]) //逐位比较两数组元素,将小者存入c数组,然后移位
c[k++]=a[i++];
else
c[k++]=b[j++];
}
while(j<length_b) //i已指向a数组末尾,将b数组剩下的元素填入c数组
c[k++]=b[j++];
while(i<length_a) //j已指向b数组末尾,将a数组剩下的元素填入c数组
c[k++]=a[i++];
cout<<"the sorted numbers are:"<<endl;
for(k=0;k<length_c;k++)
cout<<c[k]<<" ";
}
程序运行结果为: