归并排序

一、图解归并排序

下图展示了归并排序的大致思路
在这里插入图片描述
一、分阶段
分阶段其实很好去实现,只需要使用递归就能很好的分出来
二、治阶段
我们需要将两个有序的序列合并成一个有序序列,具体的方法如下图所示:
假如有两个有序序列【4、5、7、8】和【1、2、3、6】。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、代码实现
#include <iostream>
#include <vector>

using namespace std;

void Merge(vector<int> &input, int left, int mid, int right, vector<int> temp) 
{
	int i = left;                // i是第一段序列的下标
	int j = mid + 1;            // j是第二段序列的下标
	int k = 0;                    // k是临时存放合并序列的下标

	// 扫描第一段和第二段序列,直到有一个扫描结束
	while (i <= mid && j <= right) 
	{
		// 判断第一段和第二段取出的数哪个更小,将其存入合并序列,并继续向下扫描
		if (input[i] <= input[j]) 
		{
			temp[k++] = input[i++];
		}
		else 
		{
			temp[k++] = input[j++];
		}
	}
	// 若第一段序列还没扫描完,将其全部复制到合并序列
	while (i <= mid) 
	{
		temp[k++] = input[i++];
	}

	// 若第二段序列还没扫描完,将其全部复制到合并序列
	while (j <= right) {
		temp[k++] = input[j++];
	}

	k = 0;
	// 将合并序列复制到原始序列中
	while (left <= right) 
	{
		input[left++] = temp[k++];
	}
}

void MergeSort(vector<int> &input, int left, int right, vector<int> temp) 
{
	if (left < right) 
	{
		int mid = (right + left) >> 1;
		MergeSort(input, left, mid, temp);
		MergeSort(input, mid + 1, right, temp);
		Merge(input, left, mid, right, temp);
	}
}

void mergesort(vector<int> &input) 
{
	// 在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间
	vector<int> temp(input.size());                //这个数组必须要进行长度的初始化,也就是说input.size()一定要
	MergeSort(input, 0, input.size() - 1, temp);
}

void main()
 {
	int arr[] = { 6, 4, 8, 9, 2, 3, 1 };
	vector<int> test(arr, arr + sizeof(arr) / sizeof(arr[0]));
	cout << "排序前:";
	for (int i = 0; i < test.size(); i++)
	{
		cout << test[i] << " ";
	}
	cout << endl;

	vector<int> result = test;
	mergesort(result);
	cout << "排序后:";
	for (int i = 0; i < result.size(); i++) 
	{
		cout << result[i] << " ";
	}
	cout << endl;
	system("pause");
}
三、性能分析

(1)时间复杂度
由上图所示,发现归并排序的形式就是一颗完全二叉树,所以它要遍历的次数就是二叉树的深度,因此时间复杂度为O(logN)
(2)空间复杂度
因为它需要开辟n个空间的数组,来保存合并序列。所以空间复杂度为O(N)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值