`
qq1214917885
  • 浏览: 9103 次
文章分类
社区版块
存档分类
最新评论

浅谈快排

 
阅读更多
    今天水了一道排序题。学会了快排的方法。快排并不仅仅是分治,还要有随机。因为考虑到一些特殊的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个正序数列的运行的时间。在使用随机数的情况下很快就能得出结果。但没有使用的时候等上半天甚至没有结果。所以说快排应该是=随机取数+分治思想
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics