编程珠玑第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; }