算法分析:归并排序

归并排序:

最坏情形是O(NlogN)

使用的比较次数几乎是最优的。

这个算法中基本操作是合并两个已排序的表。

归并排序通过递归,将数组自身分拆成2个数组,然后进入子数组的排序。

分拆的数组左右两个,必须是紧跟着的。

虽然归并排序的运行时间是O(NlogN),但是很难用于主存排序,主要问题在于合并两个排序表需要额外的内存,在整个算法中还要复制数据。

归并排序的运行时间很大程度上依赖于在数组中进行元素的比较和移动所消耗的时间。

例如java中,元素比较耗时很多,移动元素就快很多,所以归并排序是一般目的的排序的最佳选择。

在C++中,对象很大的时候,复制对象代价很大,而对象比较消耗小。

	//-------------归并排序----------------------
	template<typename Comparable>
	void mergeSort(Vector<Comparable>& a)
	{
		//构建一个临时数组,用来放数据
		Vector<Comparable> temArry(a.size());
		//调用核心函数
		mergeSort(a, temArry, 0, a.size() - 1);
	}
	template<typename Comparable>
	void mergeSort(Vector<Comparable>& a, Vector<Comparable>& tmpArray, int left, int right)
	{
		if (left >= right)
		{
			return;//只有一个元素的时候,就返回了
		}
		int center = (left + right) / 2;//定义一个中心,一分为二
		mergeSort(a, tmpArray, left, center);//对左边进行归并排序
		mergeSort(a, tmpArray, center + 1, right);//对右边进行归并排序
		merge(a, tmpArray, left, center + 1, right);//合并左右两边
	}
	//合并两个已排序的队列
	template<typename Comparable>
	void merge(Vector<Comparable>& a, Vector<Comparable>& tmpArray, int leftPos, int rightPos, int rightEnd)
	{
		int leftEnd = rightPos - 1;//左边最后一位
		int tmpPos = leftPos;//临时数组中的第一个位置
		int numElements = rightEnd - leftPos + 1;//总的元素数量
		//两边都有元素的时候
		while (leftPos <= leftEnd && rightPos <= rightEnd)
		{
			//将小的放进临时数组
			if (a[leftPos] <= a[rightPos])
			{
				tmpArray[tmpPos++] = a[leftPos++];
			}
			else
			{
				tmpArray[tmpPos++] = a[rightPos++];
			}
		}
		//有一个数组是完结的了,放另一个数组的全部数据进去
		while (leftPos <= leftEnd)
		{
			tmpArray[tmpPos++] = a[leftPos++];
		}
		while (rightPos <= rightEnd)
		{
			tmpArray[tmpPos++] = a[rightPos++];
		}
		//将临时数组的数据放到原来的数组
		for (int i = 0; i < numElements; i++, rightEnd--)
		{
			a[rightEnd] = tmpArray[rightEnd];
		}
	}


转载于:https://www.cnblogs.com/fablegame/p/6430201.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值