【混合排序】(STL std::sort | 快速排序 | 插入排序 | 堆排序)

文章介绍了C++STL中的std::sort函数实现,尤其是IntroSort算法,它结合了median-of-threeQuickSort策略,能自动切换到HeapSort以应对性能下降。文中还提及了pivot选择和内存管理的细节。
摘要由CSDN通过智能技术生成
/*
	std::sort 的实现基于 David Musser 1996年提出的一种混合式排序算法 Introspective Sorting,
即IntroSort,其行为几乎与median-of-three QuickSort完全相同,
但是当Partition有恶化的倾向时,能够自我侦测,转而改用HeapSort,
使复杂度维持在HeapSort的 O(NlonN)。
—— 侯捷《STL源码剖析》
std::sort在最后,会在整个数组上做一次插入排序。
ntrosort在GCC源码中涉及了两处 以__unguarded__...... 为名的函数,
它们的名字暗示了它们不会做越界检查。

在快排中 pivot的选择是一件non-trivial的事情,
introsort选用了median-of-three方法,
这又与一个 __unguarded 函数产生了联动。
*/

#define _THRESHOLD_VALUE_ 16 
#define regUInt \
	register unsigned int
void QuickSort(int A[],int beg,int end,int depMon,int N)
{
	if(beg+1+_THRESHOLD_VALUE_ >= end){
		BinaryInsertSort(A,beg,end);//改用二分插入排序插入 
		return;
	}
	if(depMon > log2(N)){
		HeapSort(A,beg,end);
		//递归深度大于log2N阈值 改成堆排序 
		return;
	}
	int mid = beg + ( (end-beg)>>1 ),
		rbeg = end-1;
	if(A[beg] > A[mid])swap(&A[beg],&A[mid]);
	if(A[rbeg] > A[mid])swap(&A[rbeg],&A[mid]);
	if(A[beg] > A[rbeg])swap(&A[beg],&A[rbeg]);
	//三者取中 后置 
	regUInt i = beg,
			_Pivot = rbeg,
		    j = _Pivot-1,
		    k,r;
	while(i < j)
	{
		while((i < j) && A[j] > A[_Pivot])--j;
		while((i < j) && A[i] <= A[_Pivot])++i;
		if(i < j)swap(&A[i],&A[j]);
	}	
	swap(&A[_Pivot],&A[!(i == j)?j:++j]);
	swap(&_Pivot,&j);
	r = _Pivot-1;
	for(r = _Pivot,k = beg;k < _Pivot;++k)
		if(A[k] == A[_Pivot])swap(A[k],A[--r]);
	//元素聚集 
	QuickSort(A,beg,r,depMon+1);
	QuickSort(A,_Pivot+1,end,depMon+1);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XNB's Not a Beginner

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值