归并排序

归并排序:
用二分的思想把一个排序问题分解成若干个子问题,在每个子问题解决之后再把子问题合并,通过递归 的方式实现。

#include<iostream>
using namespace std;

void merge(int a[], int left, int mid, int right)
{
	int* ans= new int [right - left + 1];         // 开辟一片空间(大小和原数组相等),用指针索引,这个空间就是合并之后下面那个数组,空间大小不一定是right+1!
	int p1 = left;                                // 左数组开始时的索引
	int p2 = mid+1;                               // 右数组开始时的索引
	int i = 0;                                    // 新数组的索引

	while (p1 <= mid&& p2 <= right)               // 两索引只要有一个到头了就结束
	{
		// 如果是右边数组当前元素的大,就把右边数组当前元素的值插入新数组的后面,P2指向下一个元素
		if (a[p1] <=a[p2])
		{
			ans[i++] = a[p2];
			p2++;
		}

		// 反之亦然
		else
		{
			ans[i++] =a[p1];
			p1++;
		}
	}

	// 全部比较完之后,看看哪边有剩余

	// 若左子数组有剩余,则把左边的插入末尾(左数组本身已经排好序)
	while (p1 <= mid)
	{
		ans[i++] = a[p1];
		p1++;
	}

	// 右子数组剩余时,也是相同操作(等于的时候也要,因为等于的时候只是下标到那里,其实还没执行)
	while (p2 <= right)
	{
		ans[i++] = a[p2];
		p2++;
	}
	//  赋值到原数组
	for (int i = 0; i < right-left+1; i++)
	{
		a[i+left] = ans[i];         // 赋值从a[left]开始
	}

	delete[]ans;      // 防止内存泄漏
}
void merge_sort(int a[], int left, int right)
{
	if ((right - left + 1) < 2)        // 只有一个元素的时候为出口
		return;
	if (left >= right)
		return;

		int mid = ((right + left) / 2);
		merge_sort(a, mid + 1, right);         //   进行左半部分排序
		merge_sort(a, left, mid);              //   进行右半部分排序
		merge(a, left, mid, right);            //   调用merge函数合并两已经排好的部分
	
}


int main()
{
	int a[10] = { 2,4,6,8,5,3 };
	merge_sort(a, 0, 5);
	for (int i = 0; i < 6; i++)
		cout << a[i];
	return 0;

}

用递归树来理解上面的测试例子:

在这里插入图片描述
递归树深度logn,每层O(n):时间复杂度O(nlogn)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值