排序算法(七) 2路归并排序

一、什么是归并排序?

       归并排序的特点体现在 “归并” 上,“归并” 就是“合并”!将两个或两个以上有序的序列合并为一个有序的序列。而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;
}

五、运行截图:

                                     


发布了51 篇原创文章 · 获赞 55 · 访问量 7万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章