编程珠玑——排序算法

编程珠玑第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; } 
            
           
          
         
       
      
      
     
     
    
    
   
   
  
  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值