八大排序之二路归并排序(4)

归并排序

首先将所有数据默认每个数据单独分成一个组,接下来两两合并,当所有数据在同一个组内,则排序完成。

排序规则
  1. 将所有数据单独给每个数每个组(每个数据单独看,就是有序的)
  2. 然后将数据进行两两合并成一组,对每一组数据进行排序
  3. 然后继续把数据两两合并排序,直到只有一组数据

原始数据: 84   9   18  19   48  12   90   84   90   12

第一次两两合并: 9 84   18 19  12 48  84 90   8 12
第二次两两合并:9 18 19 84   12 48 84 90  8 12
第三次两两合并:9 12 18 19 48 84 84 90  8 12
第四次两两合并:8 9 12 12 18 19 48 84 84 90

代码实现
//二路归并排序

//一次合并函数
void Merge(int* arr, int len, int gap)
{
	int* brr = (int*)malloc(sizeof(int) * len);
	assert(brr != NULL);
	int low1 = 0;
	int high1 = low1 + gap - 1;
	int low2 = high1 + 1;
	int high2 = low2 + gap - 1 < len ? low2 + gap - 1 : len - 1;
	int i = 0;  //指向辅助空间下标
	while (low2 < len)   //确保左右两个组都有数据
	{
		while (low1 <= high1 && low2 <= high2)//保证两个组内都有数据去比较
		{
			if (arr[low1] <= arr[low2])
			{
				brr[i++] = arr[low1++];
			}
			else
			{
				brr[i++] = arr[low2++];
			}
		}

		//此时肯定有一个组为空,需要判断哪个组为空,需要做对应的处理
		//
		while (low1 <= high1)
		{
			brr[i++] = arr[low1++];
		}
		while (low2 <= high2)
		{
			brr[i++] = arr[low2++];
		}
		// 此时应该继续往后选取两个组
		low1 = high2 + 1;
		high1 = low1 + gap - 1;
		low2 = high1 + 1;
		high2 = low2 + gap - 1 < len ? low2 + gap - 1 : len - 1;
	}
	//此时最外层循环退出,此时有两种可能性:前一个组有数据,后一个组空;要么两个组都没有数据
	while (low1 < len)
	{
		brr[i++] = arr[low1++];
	}

	//最后将brr数据放到原数组中
	for (int i = 0; i < len; i++)
	{
		arr[i] = brr[i];
	}
	free(brr);
}
void MergeSort(int* arr, int len)
{
	for (int i =1;i<len;i*=2)
	{
		Merge(arr, len, i);
	}
}

测试

16)

算法复杂度分析

时间复杂度: O ( n ⋅ log ⁡ n ) O(n\cdot \log n ) O(nlogn) 由于一次合并函数需要n次,一共需要$\log n $ 次
空间复杂度: O ( n ) O(n) O(n) 每一次分组排序,需要借助n个辅助空间

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值