归并排序是很有效的一种排序算法,是分治法(Divide and Conquer)的非常典型的应用。普通的排序,比如选择排序,插入排序或者冒泡排序的时间复杂度为O(N^2),而归并排序可以达到O(N*logN),在当N非常大时能够节省很多的时间。归并,顾名思义,就是Divide(将长度为N的序列分为两个N/2的子序列),Conquer(对这两个子序列分别用到归并排序),和Combine(将两个排序好的子序列合并)的过程。
以一个简单的排序为例,对数组a[11]={25,10,7,19,3,48,12,17,56,30,21}进行排序,以下是C++代码。
#include <iostream>
using namespace std;
//对数组进行合并与排序
void Merge(int a[],int first,int mid,int last,int temp[])//temp[]为辅助数组负责记录排序好的数组
{
int i=first;
int j=mid+1;
int k=0;
int n=last;
int m=mid;
while(i<=m&&j<=n)
{
if(a[i]<a[j])
{
temp[k++]=a[i++];
}
else
{
temp[k++]=a[j++];
}
}
while(i<=m)
{
temp[k++]=a[i++];
}
while(j<=n)
{
temp[k++]=a[j++];
}
for(int i=0;i<k;i++)
{
a[first+i]=temp[i];//注意这里是first+1,因为temp每次是从0开始,而要赋值的数组a[]是总序列。
}
}
void Mergesort(int a[],int first,int last,int temp[])//直到为一个元素时默认为排序好,进行递归。
{
if(first<last)
{
int mid=(first+last)/2;
Mergesort(a,first,mid,temp);//左边有序
Mergesort(a,mid+1,last,temp);//右边有序
Merge(a,first,mid,last,temp);
}
}
int main()
{
int a[11]={25,10,7,19,3,48,12,17,56,30,21};
int temp[11];
for(int i=0;i<=10;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
Mergesort(a,0,10,temp);
for(int i=0;i<=10;i++)//输出排序好的数组
{
cout<<a[i]<<" ";
}
return 0;
}