在上一篇文章中实现了递归方法的归并排序。归并排序时间效率很好,虽然使用递归的方法实现很简单易读,但是容易造成空间性能上的损耗(反复的函数调用引起)。因此,有采用循环的方式实现归排序。给出了两种写法,一种是我自己写的(第一种),一种是weiss书上的课后习题的参考答案(第二种),思想是一样的,第二种明显比第一种写法简单很多。
程序如下
#include<iostream>
#include<vector>
#include<random>
#include<ctime>
#include<iterator>
#include<algorithm>
using namespace std;
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];
}
template<typename Comparable>
void mergeSortLoop(vector<Comparable> &a)
{
vector<Comparable> tmpArray(a.size());
int numElements = a.size();
for (size_t k = 1; k < a.size(); k *= 2)
{
int leftStart = 0;
int gap = 2 * k;
while ((leftStart + gap) < numElements)
{
merge(a, tmpArray, leftStart, leftStart + k, leftStart + gap - 1);
leftStart += gap;
}
if ((numElements - leftStart) > k)
{
merge(a, tmpArray, leftStart, leftStart + k, numElements-1);
}
}
}
template<typename T>
void printVector(vector<T> & v)
{
copy(v.cbegin(), v.cend(), ostream_iterator<T>(cout, " "));
cout << endl;
}
int main()
{
vector<int> source;
uniform_int_distribution<int> u(0, 1000);
default_random_engine e(static_cast<unsigned int>(time(0)));
for (int i = 0; i < 31; i++)
{
source.push_back(u(e));
}
cout << "排序前:" << endl;
printVector(source);
mergeSortLoop(source);
cout << "排序后:" << endl;
printVector(source);
return 0;
}
结果如图
 |