快排改进

快排是平均性能最好的排序算法,但是当面对初始有序序列时,速度将会退化到O(n2)。

有一天我就想怎么能把快排在初始有序时排序速度提高,于是在纸上写下一串有序序列,分析其规律,突然发现,如果选择中间的数作为枢轴,是否就能解决这个问题呢?

说干就干,当天用了一下午的时间,对快排进行了改进。


int PationUp(SqList &L,int low,int high)
{//快排升级版,
	int pivot;   //枢轴
	pivot=(high+low)/2;	
	L.r[0]=L.r[pivot];
	while(low
   
   
    
    L.r[0].key)
			--high;
		L.r[pivot]=L.r[high];
		pivot=high;
		while(low
    
    
   
   



在无序时,两种快排速度相差无几,而当初始有序时,改进后的快排速度达到对无序序列排序时的一半,以一亿个随机数为例,在我的电脑上,快排预计需要半年,而改进后的快排只需11秒。


但是,进一步测试发现,当面对含有大量相等元素的序列时,两种快排都会再次退化回O(n2),于是,我采用 if 来控制循环次数,达到两端交替走的效果,当元素全部相等会在正中间分开,避免了一边先走直接走到另一端的情况。不过可能是比较次数过多,略微牺牲了其他情况下的排序性能。


int Pation2(SqList &L,int low,int high)
{	
	int pivot;   
	pivot=(high+low)/2;	
	L.r[0]=L.r[pivot];
	while(low
    
    
     
     =L.r[0].key)
			--high;
		if(L.r[high].key<=L.r[0].key)
		{
			L.r[pivot]=L.r[high];
			pivot=high;
		}
		if(low
     
     
      
      =L.r[0].key)
		{
			L.r[pivot]=L.r[low];
			pivot=low;
		}
	}
	L.r[pivot]=L.r[0];
	return pivot;
}

void Qsort2(SqList &L,int low,int high)
{
	int j;
	if(low
      
      
     
     
    
    


注:1到10等值,是指,比如生成一个含有一万个数的序列,取值范围为1到10,每个数出现的次数为10000/10=1000次。因为我在测试时发现,代码中判定条件的微小差异会对不是所有数都等值的序列造成非常大的影响。

代码中

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值