编程珠玑第11章讲解的几种排序算法的C++实现
#include "stdafx.h"
#include
#include
#include
#include "windows.h"
using namespace std;
template< typename InPos >
inline void isort( InPos posBegin_, InPos posEnd_ )
{
/// 通过_Val_type函数获取到迭代器指向的数据类型
_isort(posBegin_, posEnd_, _Val_type(posBegin_));
}
/// 插入排序,最坏情况下为O(n^2)
template< typename InPos, typename ValueType >
void _isort( InPos posBegin_, InPos posEnd_, ValueType* )
{
/****************************************************************************
* 伪代码如下:
* for i = [1, n)
* t = x[i]
* for( j = i; j > 0 && x[j-1] > t; j-- )
* x[j] = x[j-1]
* x[j] = x[j-1]
****************************************************************************/
if( posBegin_ == posEnd_ )
{
return;
}
/// 循环迭代,将每个元素插入到合适的位置
for( InPos pos = posBegin_; pos != posEnd_; ++pos )
{
ValueType Val = *pos;
InPos posPrev = pos;
InPos pos2 = pos;
/// 当元素比前一个元素大时,交换
for( ;pos2 != posBegin_ && *(--posPrev) > Val ; --pos2 )
{
*pos2 = *posPrev;
}
*pos2 = Val;
}
}
/// 快速排序1,平均情况下需要O(nlogn)的时间
template< typename InPos >
inline void qsort1( InPos posBegin_, InPos posEnd_ )
{
/****************************************************************************
* 伪代码如下:
* void qsort(l, n)
* if(l >= u)
* return;
* m = l
* for i = [l+1, u]
* if( x[i] < x[l]
* swap(++m, i)
* swap(l, m)
* qsort(l, m-1)
* qsort(m+1, u)
****************************************************************************/
if( posBegin_ == posEnd_ )
{
return;
}
/// 将比第一个元素小的元素移至前半部
InPos pos = posBegin_;
InPos posLess = posBegin_;
for( ++pos; pos != posEnd_; ++pos )
{
if( *pos < *posBegin_ )
{
swap( *pos, *(++posLess) );
}
}
/// 把第一个元素插到两快元素中央
swap( *posBegin_, *(posLess) );
/// 对前半部、后半部执行快速排序
qsort1(posBegin_, posLess);
qsort1(++posLess, posEnd_);
};
/// 快速排序2,原理与1基本相同,通过两端同时迭代加快平均速度
template
void qsort2( InPos posBegin_, InPos posEnd_ )
{
if( distance(posBegin_, posEnd_) <= 0 )
{
return;
}
InPos posL = posBegin_;
InPos posR = posEnd_;
while( true )
{
/// 找到不小于第一个元素的数
do
{
++posL;
}while( *posL < *posBegin_ && posL != posEnd_ );
/// 找到不大于第一个元素的数
do
{
--posR;
} while ( *posR > *posBegin_ );
/// 两个区域交叉时跳出循环
if( distance(posL, posR) <= 0 )
{
break;
}
/// 交换找到的元素
swap(*posL, *posR);
}
/// 将第一个元素换到合适的位置
swap(*posBegin_, *posR);
/// 对前半部、后半部执行快速排序2
qsort2(posBegin_, posR);
qsort2(++posR, posEnd_);
}
/// 当元素个数小与g_iSortMax时使用插入排序,g_iSortMax是根据STL库选取的
const int g_iSortMax = 32;
/// 该排序算法是快速排序与插入排序的结合
template
void qsort3( InPos posBegin_, InPos posEnd_ )
{
if( distance(posBegin_, posEnd_) <= 0 )
{
return;
}
/// 小与g_iSortMax时使用插入排序
if( distance(posBegin_, posEnd_) <= g_iSortMax )
{
return isort(posBegin_, posEnd_);
}
/// 大与g_iSortMax时使用快速排序
InPos posL = posBegin_;
InPos posR = posEnd_;
while( true )
{
do
{
++posL;
}while( *posL < *posBegin_ && posL != posEnd_ );
do
{
--posR;
} while ( *posR > *posBegin_ );
if( distance(posL, posR) <= 0 )
{
break;
}
swap(*posL, *posR);
}
swap(*posBegin_, *posR);
qsort3(posBegin_, posR);
qsort3(++posR, posEnd_);
}
int random( int iStart_, int iEnd_ )
{
return iStart_ + rand()%(iEnd_ - iStart_);
}
int _tmain(int argc, _TCHAR* argv[])
{
srand(unsigned int(time(0)));
vector coll;
for( int i = 0; i< 100000; ++i )
{
coll.push_back(random(0, 10000));
}
DWORD dwStart, dwEnd;
vector collCopy(coll);
dwStart = GetTickCount();
isort(collCopy.begin(), collCopy.end());
dwEnd = GetTickCount();
cout << dwEnd - dwStart << endl;
vector collCopy2(coll);
dwStart = GetTickCount();
qsort1(collCopy2.begin(), collCopy2.end());
dwEnd = GetTickCount();
cout << dwEnd - dwStart << endl;
vector collCopy3(coll);
dwStart = GetTickCount();
qsort2(collCopy3.begin(), collCopy3.end());
dwEnd = GetTickCount();
cout << dwEnd - dwStart << endl;
vector collCopy4(coll);
dwStart = GetTickCount();
qsort3(collCopy4.begin(), collCopy4.end());
dwEnd = GetTickCount();
cout << dwEnd - dwStart << endl;
return 0;
}#include "stdafx.