归并排序是多次将两个或两个以上的有序表合并成一个新的有序表。其每趟归并产生的有序区间只是局部有序,也就是说,在最后一趟排序结束前,所有元素不一定归为。
实现代码如下:
/*
Author:Ibsen
Data:2015.12.22
*/
//归并排序:时间O(n*logn),空间O(n),稳定
#include <iostream>
#include <cstdlib>
using namespace std;
int R[]={2,4,6,8,0,9,7,5,3,1},n=10;
void Merge(int R[],int low,int mid,int high)
{//将两个有序表直接归并
int *R1;
int i=low,j=mid+1,k=0; //k为R1的下标,i,j分别为R[]的第1,2段下标
R1=(int *)malloc((high-low+1)*sizeof(int));
while(i<=mid&&j<=high)
{
if(R[i]<=R[j]) R1[k++]=R[i++];//将第1段中的元素放入R1中
else R1[k++]=R[j++]; //将第2段中的元素放入R1中
}
while(i<=mid) R1[k++]=R[i++]; //将第1段剩下的元素放入R1中
while(j<=high) R1[k++]=R[j++]; //将第2段剩下的元素放入R1中
for(k=0,i=low;i<=high;k++,i++) R[i]=R1[k]; //将R1复制回R中
free(R1);
}
void Merge_Pass(int R[],int len,int n)
{//对整个表进行一趟归并排序
int i=0;
for(;i+2*len-1<n;i+=2*len) //每次归并长度为len的两个相邻字表
Merge(R,i,i+len-1,i+2*len-1);
if(i+len-1<n) Merge(R,i,i+len-1,n-1); //余下两个字表,后者长度小于len,将其归并
}
void Merge_Sort(int R[],int n)
{//自底向上的二路归并排序
for(int len=1;len<n;len*=2) //进行logn趟归并
Merge_Pass(R,len,n);
}
void Display(int R[],int n)
{//打印输出排序后的结果
for(int i=0;i<n;i++)
cout<<R[i]<<" ";
cout<<endl;
}
int main()
{
Merge_Sort(R,n);
Display(R,n);
return 0;
}