/****************************************************************
**归并排序的实现,其中包括递归实现和非递归实现,非递归实现***
**采用两种方式:1,利用栈实现非递归(即模拟递归过程)2,不***
**利用栈实现。在实现merge函数时,也采用两种方法:1,辅助数***
**组在merge中定义;2,辅助数组在merge外定义********************
****************************************************************/
#ifndef MERGE_SORT_H
#define MERGE_SORT_H
#include<vector>
#include<stack>
#include<iostream>
#include<algorithm>
#include<numeric>
using std::cout;
using std::endl;
using std::cerr;
template<typename T>
void MergeSort(T* list, int low, int high);
template<typename T>
void MergeSortNonrecursive(T *list, int low, int high);
template<typename T>
void MergeSortNonrecursive1(T *list, int low, int high);
template<typename T>
void Merge(T* list, int low, int mid, int high);
template<typename T>
void MergePass(T *list, const int& start, const int& end, const int& step_length);
template<typename T>
struct Info
{
T low;
T mid;
T high;
bool last_processed;
Info() {}
Info(T lo, T m, T hi):low(lo), mid(m), high(hi),last_processed(false) {}
};
//方法1,归并排序的实现:在merge函数中再定义辅助数组,用的空间相对较小但容易产生很多内存碎片
template<typename T>
void MergeSort(T* list, int low, int high)
{
int mid = -1;
if(low < high)
{
mid = ((high - low) >> 1) + low;
MergeSort(list, low, mid);
MergeSort(list, mid + 1, high);
Merge(list, low, mid, high);
}
}
//利用栈的非递归 归并排序1
template<typename T>
void MergeSortNonrecursive1(T *list, int low, int high)
{
int mid = -1;
std::stack<Info<T> > s;
Info<T> parameter;
while(low < high || !s.empty())
{
while(low < high)
{
mid = (low + high) / 2;
s.push(Info<T>(low, mid, high));
high = mid;
}
if(!s.empty())
{
parameter = s.top();
s.pop();
if(parameter.last_processed == true)
{
Merge(list, parameter.low, parameter.mid, parameter.high);
low = high;
}
else
{
parameter.last_processed = true;
s.push(parameter);
low = parameter.mid + 1;
high = parameter.high;
}
}
}
}
//不利用栈的非递归 归并排序
template<typename T>
void MergeSortNonrecursive(T *list, int low, int high)
{
int step_length = 1; //需要归并的子序列长度,开始为1
while(step_length < (high - low + 1))
{
MergePass(list, low, high, step_length);
step_length *= 2;
}
}
//子序列长度为step_length时进行一次归并。
template<typename T>
void MergePass(T *list, const int& start, const int& end, const int& step_length)
{
int i= start;
while(i <= (end - 2 * step_length + 1))
{
Merge(list, i, i + step_length - 1, i + 2 * step_length - 1);
i = i + 2 * step_length;
}
if(i < end - step_length + 1)
{
Merge(list, i, i + step_length - 1, end);
}
}
//借助temp[mid+1..high]将list[low...mid]和list[mid+1..high]按从下到大归并到list[low...high]
template<typename T>
void Merge(T* list, int low, int mid, int high)
{
int k = low; //k用于循环list[low...high]中的元素
int j = mid + 1; //j用于循环list[mid+1...high]中的元素
int i = 0; //i用于循环temp中的元素
T* ptemp = new T[mid - low + 1]; //可以用vector
if(!ptemp)
{
cerr << "failed to allocate memory!!";
return;
}
//将list[low...mid]copy到temp中
for(int m = low; m <= mid; ++m)
{
ptemp[i++] = list[m];
}
i = 0;
//将temp[0...mid-low+1]和list[mid+1..high]按从下到大归并到list[low...high]
while(i < mid-low+1 && j <= high)
{
if(ptemp[i] <= list[j])
{
list[k++] = ptemp[i++];
}
else
{
list[k++] = list[j++];
}
}
//如果temp中还有剩余的元素,将其拷贝到list中去
while(i < mid-low+1)
{
list[k++] = ptemp[i++]; //将剩余的list[low...mid]复制到list_merged
}
delete []ptemp;
}
//方法2:
//归并排序的实现:开始就设定辅助数组,需要的空间稍大但不容易产生内存碎片
template<typename T>
void MergeSort(T* arr ,int length)
{
T* temp = new T[length];
MergeSort(arr, temp, 0, length-1);
delete[] temp;
}
template<typename T>
void MergeSort(T* arr, T* help, int low, int high)
{
if(low < high)
{
int mid = (high - low) >> 1 + low;
MergeSort(arr, help, low, mid);
MergeSort(arr, help, mid +1, high);
Merge(arr,help,low, mid, high);
}
}
//将有序的list[low...mid]copy 到 help[low...mid]
//然后将help[low...mid]和list[mid+1..high]按从下到大归并到list[low...high]
template<typename T>
void Merge(T* list, T* help, int low, int mid, int high)
{
int i = low; //i用于循环help[low...mid]中的元素
int j = mid + 1; //j用于循环list[mid+1...high]中的元素
int k = low; //k用于循环list[low...high]中的元素
while(i <= mid) //list[low...mid] copy 到 help[low...mid]
{
help[i] = list[i];
++i;
}
i = low;
while(i <= mid && j <= high)
{
if(help[i] <= list[j])
{
list[k++] = help[i++];
}
else
{
list[k++] = list[j++];
}
}
while(i <= mid)
{
list[k++] = help[i++]; //将剩余的help[i...mid]复制到list中
}
}
#endif // MERGE_SORT_H