归并排序

 归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

首先考虑下如何将将二个有序数列合并。这个非常简单,只要从比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可。

数据结构与算法分析C++描述中图解如下:

可以看出合并有序数列的效率是比较高的,可以达到O(n)。

解决了上面的合并有序数列问题,再来看归并排序,其的基本思路就是将数组分成二组,如果这二组组内的数据都是有序的,那么就可以很方便的将这二组数据进行排序。如何让这二组组内数据有序了?

可以将前,后组各自再分成二组。依次类推,当分出来的小组只有一个数据时,可以认为这个小组组内已经达到了有序,然后再合并相邻的二个小组就可以了。这样通过先递的分解数列,再合数列就完成了归并排序。


好了,废话少说,代码奉上

#include <iostream>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::begin;
using std::end;

template <class T>
void print(const vector<T> &v)
{
	for(auto &i : v)
	{
		cout << i << "  ";
	}

	cout << endl;
}


//归并排序
template <class T>
void mergeSort(vector<T> &v)//启动归并排序
{
	vector<T> temp(v.size());//temp用于连接排好序的两个数组
	mergeSort(v,temp,0,v.size()-1);
}

template <class T>
void mergeSort(vector<T> &v,vector<T> &temp,int left,int right)//left排序数组元素下标,right排序数组元素的上标
{
	if(left == right)//只有1个元素了,无需排序,直接返回
	{
		return;
	}
	else
	{
		int middle = (left + right)/2;
		mergeSort(v,temp,left,middle);//左半部分排序------分的体现
		mergeSort(v,temp,middle+1,right);//右半部分排序-----分的体现
		merge(v,temp,left,middle,right);//对整个上、下部分合并-----治的体现
	}
}

template <class T>
void merge(vector<T> &v,vector<T> &temp,int left,int middle,int right)
{
	int leftPos = left;      //左半部分数组开始下标
	int leftEnd = middle;    //左半部分数组结束下标
	int rightPos = middle+1; //右半部分数组开始下标
	int rightEnd = right;    //右半部分数组结束下标
	int length = right - left + 1;//2个数组总的元素个数
	int tempPos = left;//第3方存贮数组开始下标

	while(leftPos <= leftEnd && rightPos <= rightEnd)//依次比较2个数组,将其中小的元素放入第3方数组
	{
		if(v[leftPos] <= v[rightPos])
		{
			temp[tempPos++] = v[leftPos++];
		}
		else
		{
			temp[tempPos++] = v[rightPos++];
		}
	}

	while(leftPos <= leftEnd)//左半部分数组未走完,依次copy至第3方数组
	{
		temp[tempPos++] = v[leftPos++];
	}

	while(rightPos <= rightEnd)//右半部分数组未走完,依次copy至第3方数组
	{
		temp[tempPos++] = v[rightPos++];
	}

	for(int i = 0; i < length;i++)//copy第3方数组元素至原数组
	{
		v[left+i] = temp[left+i];
	}
}


int main()
{
	int a[] = {5,2,4,6,1,3};
	vector<int> v = vector<int>(begin(a),end(a));

	cout<<"排序前数组:";
	print(v);

	mergeSort(v);

	cout<<"排序后数组:";
	print(v);

	system("pause");
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值