高速排序为什么快?

这是以前思考过的问题, 它为什么叫高速排序呢?思考无果,然后忘记了,然后昨天被问起。自然想不出非常好的答案。直到,看到了《暗时间》上有这个问题的答案。

 

在《暗时间》里。作者刘未然并没有直接给出答案。而是先说了两个游戏,猜数字和称球。这两个问题都非常好理解,而且不难解答。然而,令我豁然开朗的是,他们指向了同一个思想,分而治之。把问题不断分割一半又一半,直到答案水落石出。

 

回到正题,我们的目标是排序。不管哪个排序方法都是基于两两比較的。问题在于怎样才干降低比較的次数呢?举个样例,有这么一组数:12,3,4,5,1578,89,90,100200;一共11个。而且给出的初始顺序是从小到大的。 如今要排成从大到小。高速排序的思想,就是从中抽取一个数(称为基准吧),然后大于基准的在一边。小于或等于在还有一边。

比方,如今随机的抽取了78。那么12,3,4,5,15会在一边。89,90,100200会在还有一边。这时候,注意到,从这一刻開始,小于78的那些数就再也没有机会与大于78的数进行两两比較了。高速排序用了分而治之的思想,尽管,因为随机抽取。我们最好第一次抽到的是15。这样就平分了。可是没关系。忽略掉这个随机性因素,快排还是把大问题分成了两个小问题,哪怕这两个字问题不一定对等。仅仅要递归下去,结果水到渠成。

 

相反。我们看看相同是理论上与快排一样的时间复杂度(O(nlogn))的堆排序,就说最大堆吧,它把最大的元素移除后,把最后的叶子结点拿上来,是为了重建堆。可是,明显。拿上的值是要比它的两个叶子结点要小非常多的。它要比較非常多次,才干回到合适的位置。

而且。我发现,在父结点的值与子树结点的值比較前。左子树和右子树要先比較大小,然后拿出最大的那个才去跟父节点去比較大小。

两次两两比較。才换来一次有意义的交换,如此循环下去,堆排序做了非常多无用功。

 

以上,从逻辑上分析了高速排序为什么比归并排序和堆排序快的原因。但。这还是不够的。接着。从数学统计上分析他们的时间复杂度——

1)堆排序——

在构建堆的过程中,由于我们是全然二叉树从最下层最右边的非终端结点開始构建,将它与其孩子进行比較和若有必要的互换,对于每一个非终端结点来说,事实上最多进行两次比較和互换操作。因此整个构建堆的时间复杂度为O(n)。

在正式排序时,第i次取堆顶记录重建堆须要用O(logi)的时间(全然二叉树的某个结点到根结点的距离为.log2i.+1),而且须要取n-1次堆顶记录,因此,重建堆的时间复杂度为O(nlogn)。

2)归并排序——

假如用Tn)表示使用归并排序对n个元素构成的数组进行排序而使用的时间。用mergeTime来表示将两个子分组合并起来而花费的时间。

那么

Tn = T(n/2)+T(n/2) + mergetime

megeTime就是归并两个子数组所耗费的时间。以最大时间来算。最多须要n-1次来比較两个子数组的元素。然后n次移动到暂时数组中。

那么mergetime就是2n -1

因此 Tn = T(n/2)+ T(n/2) +2n -1

 

3)高速排序——

在最差的情况下,要把n个元素的数组划分,须要n次比較和n次移动。如果用T(n) 来表示使用高速排序算法来排序n个元素的数组所耗费的时间。那么

 Tn = T(n/2)+ T(n/2) +2n

 

如此看来,有人可能就想到了。从数学公式上看,归并排序还比快排要少个1呢,是不是要快些?事实上,不是这种,请注意到那几个字"最差的情况下",就是在我每次选择的基准,取决于输入的基准,都是最不理想的基准。恰好要移动最多次才干达到目的。

可是这种情况的出现的概率是1/(2^n),非常非常小。并且。这是最普通的高速排序方法。先人提出了非常多改进优化的方案。当中一种被非经常常使用的就是採用随机函数来选择基准来避免最坏的情况的发生。

 

在畅销的ACM信息竞赛教材《算法艺术与信息学竞赛》上,作者也提出了关于快排的效率与优化问题——


 

正如我们所分析的。一旦我们採用随机函数来产生基准,那么时间复杂度计算公式里。

 Tn = T(n/2)+ T(n/2) +2n 2n就不再是2n了,或许是1,或许是2...可是。最后的结果肯定是要比2n小非常多了。

 

至于堆排序。明显。堆排序主要是堆调整的时间非常耗时,90%的时间耗在堆调整上。因此在数据量大的时候。明显是要落后非常多的。

 

至此,我想我明确了为什么快排比其它两种都要快了。由于它善于分解子问题。从不做无用功。

尽管有最糟糕的情况。可是这个是能够最大限度减少其出现概率的。

有不允许见的,欢迎拍砖,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值