排序算法(4)——归并排序(2路归并排序)

归并排序

归并:将两个或两个以上的有序表组合成一个新有序表。

  • 排序过程:
    初始序列看成n个有序子序列,每个子序列长度为1;
    两两合并,得到n/2个长度为2或1的有序子序列;
    再两两合并,重复直至得到一个长度为n的有序序列为止。
  • 例子
    在这里插入图片描述
  • 代码实现
    代码可结合上面例子进行理解。
#include<iostream>
using namespace std;

//共同部分——将两个有序序列合并为一个有序序列
void Merge(int list[], int low, int m, int high)
{
	int temp[8];//暂存数组
	int i = low;
	int j = m + 1;
	int k = low;
	while (i <= m && j <= high)
	{
		if (list[i] < list[j])
			temp[k] = list[i++];
		else
			temp[k] = list[j++];
		k++;
	}
	while (i <= m)
	{
		temp[k] = list[i++];
		k++;
	}
	while (j <= high)
	{
		temp[k] = list[j++];
		k++;
	}
	for (int i = low; i <= high; i++)
		list[i] = temp[i];
}

//递归实现——begin
void mergeSort(int list[], int low, int high)
{
	if (low < high)
	{
		int mid = (low + high) / 2;
		mergeSort(list, low, mid); //将nums[low ~mid]归并为有序的 nums[low ~mid]
		mergeSort(list, mid + 1, high); //将nums[mid + 1 ~high]归并为有序的 nums[mid + 1 ~high]
		Merge(list, low, mid, high);//将有序的 nums[low ~ m] 和 nums[m+1 ~ high] 归并到 nums[low ~ high]
	}
}
//递归实现——end

//迭代实现——begin
//sonLen为子序列长度,为1,2,4,……,len为数组长度
void mSort2(int list[], int sonLen, int len)
{
	int low = 0;
	int high = low + 2 * sonLen - 1;
	while (high < len)//前面的子序列
	{
		int mid = (low + high) / 2;
		Merge(list, low, mid, high);
		low = low + 2 * sonLen;
		high = high + 2 * sonLen;
	}
	if (low < len - sonLen + 1)//将剩下不规则的子序列合并起来
		Merge(list, low, low + sonLen - 1, len - 1);
}
void mergeSort2(int list[],int len)
{
	int sonLen = 1;//子序列的归并长度从1开始迭代,之后依次乘2
	while (sonLen < len)
	{
		mSort2(list, sonLen,len);
		sonLen *= 2;
	}
}
//迭代实现——end

int main()
{
	int list[8] = { 49,38,65,97,76,13,27,49 };
	int n = sizeof(list)/sizeof(int);
	mergeSort(list, 0, n - 1);//递归实现
	mergeSort2(list,n);//迭代实现
	
	for (int i = 0; i < n - 1; i++)
		cout << list[i] << '\t';
	cout << endl;
	system("pause");
}

参考代码:github源码

  • 算法分析
    在迭代的归并排序算法中,时间复杂度为 O(nlogn),空间复杂度为 O(n)。
    在递归的归并排序算法中,时间复杂度为 O(nlogn),空间复杂度为 O(n+logn)。
    归并排序是一种稳定的排序算法。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值