【排序】归并排序

归并排序

算法思想

归并排序的思想就是利用分治算法。
分治算法: 将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解后进行合并,就可以得到原问题的解。
归并算法的实现步骤:

  1. 分解,将要解决的问题划分为若干个规模较小的同类问题
  2. 求解,当子问题划分得到足够小时,用较简单的方法解决
  3. 合并,按原问题的要求,将子问题的解逐层合并构成原问题的解。

归并排序是先将大区间划分为一个个小区间,进行排序。先局部有序,再整体有序。 (黑色为分解过程,红色为合并的过程)
在这里插入图片描述

代码实现

void merge(vector<int>& sub_vec1, vector<int>& sub_vec2,
	vector<int>& vec)
{
	int i = 0;
	int j = 0;
	while (i < sub_vec1.size() && j < sub_vec2.size())
	{
		if (sub_vec1[i] <= sub_vec2[j])
		{
			vec.push_back(sub_vec1[i]);
			i++;
		}
		else
		{
			vec.push_back(sub_vec2[j]);
			j++;
		}
	}
	for (; i < sub_vec1.size(); i++)
	{
		vec.push_back(sub_vec1[i]);
	}
	for (; j < sub_vec2.size(); j++)
	{
		vec.push_back(sub_vec2[j]);
	}
}


void merge_sort(vector<int>& vec)
{
	if (vec.size() < 2)
	{
		return; 
	}

	int mid = vec.size() / 2;
	vector<int> sub_vec1;
	vector<int> sub_vec2;
	for (int i = 0; i < mid; i++)
	{
		sub_vec1.push_back(vec[i]);
	}
	for (int i = mid; i < vec.size(); i++)
	{
		sub_vec2.push_back(vec[i]);
	}

	merge_sort(sub_vec1);
	merge_sort(sub_vec2);
	vec.clear();
	merge(sub_vec1, sub_vec2, vec);
}


int main()
{
	vector<int> v = { 6, 7, 1, 4, 4, 8, 6 };
	merge_sort(v);
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
	system("pause");
}

时间复杂度:O(N*lgN)

假设有n个元素,n个元素归并排序的时间为T(n)。
总时间 = 分解时间 + 解决子问题时间 + 合并时间
分解时间: 即对原问题拆解为两个子问题的时间复杂度O(N)
解决两个子问题的时间: 2T(n/2)
合并时间:对已排好序的数组进行合并O(N)

T(n) = 2T(n/2) + 2O(N)
= 2T(n/2) + O(N)
= O(N + 2n/2 + 4n/4 + 8n/8…)
= O(N
lgN)

也就是 在每一层都是N个节点,每一层的时间消耗都是O(N),但是二叉树中一共有logN层,所以总的时间复杂度就是O(N*logN)

空间复杂度 O(N)

用到了额外的一个数组vec,所以总的空间复杂度是O(N)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值