一、什么是归并排序?
归并排序的特点体现在 “归并” 上,“归并” 就是“合并”!将两个或两个以上有序的序列合并为一个有序的序列。而2路归并就是将两个有序序列合并为一个有序序列。
二、一个2路归并排序的图例:
三、由上图得出归并排序思路:
<1>、怎样合并两个有序序列(在后面程序中给出)
<2>、实现归并算法:将r1[ ] 中的元素用归并法排序后放到 r3[ ]中,使用一个辅助数组r2[ ] ,它的大小由参数给出(详情看代码)。
采用递归方式进行归并排序:
a、首先将r1[ ]前半部分的元素用归并法排序后放到辅助数组r2[ ]的前半部分中。
b、将r1[ ]后半部分的记录用归并法排序放到辅助数组r2[ ]的后半部分。
c、将辅助数组r2[ ]的前半部分和后半部分合并到r3[ ]中。
举例:
四、源代码实现:
/*
**函数功能: 将有序序列record1[low..mid] 和 有序序列record1[mid+1..high]合并为一个有序序列record2[low..high]
**参数说明: @record1 :有序序列1
** @low : 序列1的起始下标
** @mid : 序列1的终止下标,mid+1对应序列2的起始下标
** @high: 序列2的终止下标
** @record2 :有序序列2
**返回值 : 无
*/
void Merge(int record1[], int low, int mid, int high, int record2[])
{
//i作为record1[low..mid]的循环变量,j作为record1[mid + 1..high]的循环变量
//k作为record2[low..high]的循环变量
int i = low, j = mid + 1, k = low;
//开始合并
while ((i <= mid) && (j <= high))
{
if (record1[i] <= record1[j])
{
record2[k] = record1[i];
i++;
}
else
{
record2[k] = record1[j];
j++;
}
k++;
}
while (i <= mid)
{
record2[k] = record1[i];
k++;
i++;
}
while (j <= high)
{
record2[k] = record1[j];
k++;
j++;
}
}
/*
**函数功能: 将之前无序的序列recordBefore排序后放入recordAfter中,即函数执行完之后recordAfter为有序序列
**参数说明: @recordBefore: 无序序列存放数组
** @low : 无序序列起始下标
** @high: 无序序列终止下标
** @recordAfter : 存储有序序列的数组
**返回值 : 无
*/
void MSort(int recordBefore[], int low, int high, int recordAfter[])
{
int mid;
//辅助数组空间
int *recordMid = NULL;
//因为辅助辅助要访问到最大下标为high,所以数组长度最小为high+1
recordMid = (int *)malloc(sizeof(recordBefore[0]) * (high+1));
if (low == high)
{
recordAfter[low] = recordBefore[low];
}
else
{
mid = (low + high) / 2;
//首先将recordBefore的前半部分用归并法合并为有序,放入辅助空间recordMid中
MSort(recordBefore, low, mid, recordMid);
//再将recordBefore的后半部分用归并法合并为有序,放入辅助空间recordMid中
MSort(recordBefore, mid + 1, high, recordMid);
//最后将recordBefore的前半部分和后半部分通过合并算法,合并为有序序列放入recordAfter中
Merge(recordMid, low, mid, high, recordAfter);
//释放辅助空间
free(recordMid);
recordMid = NULL;
}
}
/*
**函数功能: 归并函数入口
**参数说明:
**@record : 序列数组 @len : 序列长度
**返回值: 无
*/
void MergeSort(int record[], int len)
{
MSort(record, 0, len - 1, record);
}
int main(void)
{
int record[] = { 0,46,55,13,42,94,17,05,70,1,2,3,4,5,6 };
int len = sizeof(record) / sizeof(record[0]);
int i = 0;
printf("归并排序前: \n");
for (i = 0;i < len;i++)
{
printf("%d ", record[i]);
}
puts("");
MergeSort(record, len);
printf("归并排序后: \n");
for (i = 0;i < len;i++)
{
printf("%d ", record[i]);
}
puts("");
return 0;
}
五、运行截图: