归并排序法的C++实现

归并排序法
归并排序法的空间代价为O(n),使用了辅助空间tempArr。
时间代价为nlogn,因为树高为logn,而每层中消耗时间为O(n)。
归并排序通过将一个长序列逐渐的划分为较小的序列,最后划分为1个个长度为1的串,然后依次进行合并。
#ifndef MERGESORT_H
#define MERGESORT_H
#include <iostream>
using namespace std;
template<typename T>
class MergeSort{
public:
	void mergeSort( T *,T *,int );
	void optimMergeSort( T *,T *,int );
	void printArr( T *,int );
};
#endif
/**
*	归并排序法  
*	先分解后合并,因此使用后序周游
*/
template<typename T> void MergeSort<T>::mergeSort( T *sortedArr,T *tempArr,int arrLength )
{
	if( arrLength<=1 )
		return;
	// 分解过程
	int left=0;
	int right=arrLength-1;
	int middle=( left+right )/2;
	mergeSort( &sortedArr[left],&tempArr[left],middle-left+1 );
	mergeSort( &sortedArr[middle+1],&tempArr[middle+1],right-middle );
	// 归并过程
	for( int i=left;i<=right;++i )
		tempArr[i]=sortedArr[i];
	int iIndex=left,jIndex=middle+1;
	while( iIndex<=middle && jIndex<=right )
	{
		if( tempArr[iIndex]<=tempArr[jIndex] )
		{
			sortedArr[left++]=tempArr[iIndex++];
		}else
		{
			sortedArr[left++]=tempArr[jIndex++];
		}
	}
	while( iIndex<=middle )
	{
		sortedArr[left++]=tempArr[iIndex++];
	}
	while( jIndex<=right )
	{
		sortedArr[left++]=tempArr[jIndex++];
	}
}

归并排序法的优化:
1、可以优化递归,含义与快速排序法类似,当子串长度较小时,不必使用递归而是使用插入排序法
2、对于合并的左右子串,使其背对背从而减少不必要的比较
/**
*	改进的归并排序
*/
template<typename T> void MergeSort<T>::optimMergeSort( T *sortedArr,T *tempArr,int arrLength )
{
	if( arrLength<=1 )
		return;
	int left=0;
	int right=arrLength-1;
	int middle=( left+right )/2;
	optimMergeSort( &sortedArr[left],&tempArr[left],middle-left+1 );
	optimMergeSort( &sortedArr[middle+1],&tempArr[middle+1],right-middle );
	// 将需要合并的两个部分背靠背合并,从而不用
	// 判断iIndex与left的关系,jIndex与middle的关系
	// 起到哨兵左右,节省不必要的比较
	for( int i=left;i<=middle;++i )
	{
		tempArr[i]=sortedArr[i];
	}
	for( int i=right;i>=middle+1;--i )
	{
		tempArr[i]=sortedArr[right-i+middle+1];
	}
	for( int iIndex=left,jIndex=right,k=left;k<=right;++k )
	{
		if( tempArr[iIndex]<=tempArr[jIndex])
		{
			sortedArr[k]=tempArr[iIndex++];
		}else
		{
			sortedArr[k]=tempArr[jIndex--];
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值