归并:将两个或两个以上的有序序列合并成一个有序序列的过程。
归并排序的主要操作是归并,其主要思想是:将若干有序序列逐步归并,最终得到一个有序序列。
基本思想:
将一个具有n个待排序记录的序列看成是n个长度为1的有序序列,
然后进行两两归并,
得到n/2个长度为2的有序序列,
再进行两两归并,得到n/4个长度为4的有序序列,
……,
直至得到一个长度为n的有序序列为止。
void Merge (int r[ ], int r1[ ], int s, int m, int t )
{
i=s; j=m+1; k=s;
while (i<=m && j<=t)
{
if (r[i]<=r[j]) r1[k++]=r[i++];
else r1[k++]=r[j++];
}
if (i<=m) while (i<=m) //收尾处理
r1[k++]=r[i++]; //前一个子序列
else while (j<=t)
r1[k++]=r[j++]; //后一个子序列
}
void MergePass (int r[ ], int r1[ ], int n, int h)
{
i=1; //第一个子序列的第一个元素
while (i≤n-2h+1) //情况1
{
Merge (r, r1, i, i+h-1, i+2*h-1);
i+=2*h;
}
if (i<n-h+1) Merge (r, r1, i, i+h-1, n); //情况2
else for (k=i; k<=n; k++) //情况3
r1[k]=r[k];
}
void MergeSort (int r[ ], int r1[ ], int n )
{
h=1;
while (h<n)
{
MergePass (r, r1, n, h);
h=2*h;
MergePass (r1, r, n, h);
h=2*h;
}
}
递归实现
void msort(int a[], int r[], int s, int t){
if(s==t)
return; //如果只有一个数字则返回,无须排序
int mid=(s+t)/2;
msort(s,mid); //分解左序列
msort(mid+1,t); //分解右序列
int i=s, j=mid+1, k=s; //接下来合并
while(i<=mid && j<=t) {
if(a[i]<=a[j]) {
r[k]=a[i]; k++; i++;
}
else {
r[k]=a[j]; k++; j++;
}
}
while(i<=mid) { //复制左边子序列剩余
r[k]=a[i]; k++; i++;
}
while(j<=t) { //复制右边子序列剩余
r[k]=a[j]; k++; j++;
}
for(int i=s; i<=t; i++)
a[i]=r[i];
return 0;
}