分治算法的思路在前一篇文章(数字旋转方阵)中已经提及,在此不做过多概述
归并排序的基本思路
先将序列平均划分成两个子序列,直到序列长度为1时,结果是将n个待排序列划分成n个长度为1的有序子序列。然后进行两两合并,直到得到一个长度为n的有序子序列。
//合并子序列
void Merge(int r[],int r1[],int s,int m,int t) //r1为辅助数组,用于临时存放r数组当前有序的序列,s—r数组低端的下标,t—高端的下标
{
int i=s,j=m+1,k=s; //k用于存放r1数组当前即将要放入元素的下标
while(i<=m && j<=t) //前段有序区低端的下标<=前段有序区的高端下标 (即m对应的位置)并且 后段有序区的低端下标<=后段有序区高端的下标
{ //if-else 语句找出r[i]和r[j]中的较小者,并将其放入r1[k]中,放入之后自加1
if(r[i]<=r[j])
r1[k++]=r[i++];
else
r1[k++]=r[j++];
}
while(i<=m) //对第一个子序列没处理完的地方进行收尾工作
r1[k++]=r[i++];
while(j<=t) //对第二个子序列没处理完的地方进行收尾工作
r1[k++]=r[j++];
}
//对数组进行归并排序
void MergeSort(int r[],int s,int t)
{
int m,r1[1000]; //r1为临时数组,将其大小假设为1000
if(s==t) //s==t说明该序列只有一个元素,序列有序,递归的出口
return;
else
{
m=(s+t)/2; //平均划分,找出序列中位数的下标
MergeSort(r,s,m); //对前半段子序列进行归并排序
MergeSort(r,m+1,t); //对后半段子序列进行归并排序
Merge(r,r1,s,m,t); //将前半段和后半段子序列合并,并将有序的结果存在r1中
for(int i=s;i<=t;i++) //将r1中的有序序列传到r中
r[i]=r1[i];
}
}