归并排序法
归并排序法的空间代价为O(n),使用了辅助空间tempArr。
时间代价为nlogn,因为树高为logn,而每层中消耗时间为O(n)。
归并排序通过将一个长序列逐渐的划分为较小的序列,最后划分为1个个长度为1的串,然后依次进行合并。
归并排序法的优化:
1、可以优化递归,含义与快速排序法类似,当子串长度较小时,不必使用递归而是使用插入排序法
2、对于合并的左右子串,使其背对背从而减少不必要的比较
归并排序法的空间代价为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--];
}
}
}