归并排序是多次将两个或两个以上的有序表合并成一个新的有序表。
最简单的归并是直接将两个有序的子表合并成一个有序的表。
Merge()实现了一次归并 :
void Merge(RecType R[],int low,int mid,int high)
{ RecType *R1;
int i=low,j=mid+1,k=0;
//k是R1的下标,i、j分别为第1、2段的下标
R1=(RecType *)malloc((high-low+1)*sizeof(RecType));
while (i<=mid && j<=high)
if (R[i].key<=R[j].key) //将第1段中的记录放入R1中
{ R1[k]=R[i]; i++;k++; }
else //将第2段中的记录放入R1中
{ R1[k]=R[j]; j++;k++; }
while (i<=mid) //将第1段余下部分复制到R1
{ R1[k]=R[i]; i++;k++; }
while (j<=high) //将第2段余下部分复制到R1
{ R1[k]=R[j]; j++;k++; }
for (k=0,i=low;i<=high;k++,i++) //将R1复制回R中
R[i]=R1[k];
free(R1);
}
MergePass()实现了一趟归并 :
void MergePass(RecType R[],int length,int n)
{ int i;
for (i=0;i+2*length-1<n;i=i+2*length) //归并length长的两相邻子表
Merge(R,i,i+length-1,i+2*length-1);
if (i+length-1<n) //余下两个子表,后者长度小于length
Merge(R,i,i+length-1,n-1); //归并这两个子表
}
二路归并排序算法如下:
void MergeSort(RecType R[],int n){ int length;
for (length=1;length<n;length=2*length)
MergePass (R,length,n);
}
例1 设待排序的表有8个记录,其关键字分别为{18,2,20,34,12,32,6,16,1,5}。说明采用归并排序方法进行排序的过程。
容易看出,对 n 个记录进行归并排序的时间复杂度为Ο(nlogn)。
即:每一趟归并的时间复杂度为 O(n),总共需进行 log2n 趟。