浅谈快排

今天水了一道排序题。学会了快排的方法。快排并不仅仅是分治,还要有随机。因为考虑到一些特殊的case可能会影响复杂度。先讲一下快排的分治思想吧。。。
在一个给定的数列中,从第一个数开始,依次往后,每当小于数列最后一个数(此数最好是由随机数产生)时,便记录下来,最后将最后一个数与刚才最后一个的后一个数进行exchange。那么一次下来。就变成了三部分,两个数列和一个数,前一部分虽是乱序,但均比某个数小。。。而后一部分则均比某一个数大。。。那么由此,就可以想到。不断的递归下去。不断的划分。到最后,就可以将原来的数列分成许多小部分。每一个部分由3个数组成。“小,中,大”,并依次排序。。。即完成了排序。。。。。
那么讨论这个快排的复杂度,因为分治的方法是多线程的。自然会比暴力解法单线程的快得多。那么在多线程的情况下,怎么达到最优呢。这里就要对应到前面提到的产生随机数。因为并不知道会得到怎么样的一个数列,如果是正序的一个庞大数列,那么如果每次都取最后一个数,则会退化到跟暴力解相同的复杂度。为防止算法退化,我们这里使用(rand() % (a-b+1))+b来得到[a,b]之间的随机数。则会尽可能的接近中间数。那么复杂度将会大大减少,。
例如,
int RAND(int A[], int p, int r)
{
int i = (rand() % (r - p)) + p;
int temp = A[i];
A[i] = A[r];
A[r] = temp;

return partition(A, p, r);

}
然后在quicksort中调用RAND而不是直接partition
另外,数列中经常会有很多重复的数,要防止这种情况下的退化,可以在判断不相等之后再进行quicksort调用,例如
while (s>0)
{
if(A[s-1]!=A[s])
{
quick(A, p, s-1);
break;
}

else s--;
}
while (q<r)
{
if(A[q+1]!=A[q])
{
quick(A, q+1, r);
break;
}

else q++;


对于测试时间
clock_t start,end;
start=clock();
end=clock();
printf("%d\n",end-start);
自己也是用这个测试过用文件读入的10W个正序数列的运行的时间。在使用随机数的情况下很快就能得出结果。但没有使用的时候等上半天甚至没有结果。所以说快排应该是=随机取数+分治思想
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值