算法导论--快速排序

来源:互联网 发布:dirt rally mac 编辑:程序博客网 时间:2024/06/05 16:18

快速排序算法最坏情况下有O(n^2)的时间复杂度,但是在实践过程中快速排序往往有很好的平均性能,在O(nlogn)中的常数项很小。《算法导论》里有很多快速排序的分析,在这里我们不做太多的数学分析,仅仅从直觉上来谈这个算法。不仅如此,《算法导论》里的Partitioning算法也和我之前在国内教材上看的不一样,而且更容易理解。
快速排序采用“分治法”的思想,递归解决问题。

这里写图片描述

这里的输入时一个数组A,然后给下标从p到r之间的数排序。
对递归比较熟练的同学应该一下就能看懂这种代码,就3行而已。

接下来是最关键的Partitioning算法
伪代码如下:

这里写图片描述

解释一下,这个算法最终生成的结果是A[r]左边的元素都小于等于A[r],A[r]右边的元素都大于等于A[r]。
举个实际例子:
这里写图片描述

很简单,最后4的左边都比4小,4的右边都比4大。

接下来分析一下快速排序的性能,分为最坏情况,最好情况和一般情况。

最坏情况下:

最坏情况下发生在当partitioning算法生成了两个子问题:一个有n-1个元素,一个有0个元素。这种很不平衡的划分导致一下递归式:
这里写图片描述
直觉上,如果我们把每一层递归所花费的时间加起来,我们会得到一个多项式,很显然这个复杂度是O(n^2)。所以如果partitioning每次划分都不平衡的话,时间复杂度是O(n^2),在基本有序的情况下,插入排序的时间复杂度是O(n)

最好的情况

最好的情况其实就是,partitioning算法划分了两个规模几乎一样的子问题,递归式如下:
这里写图片描述
我们把每一次递归所花费的时间加起来,得到的最后的复杂度为O(nlgn)

一般情况

一般情况下, 快排的时间花费很接近最好情况,也就是说,
这里写图片描述
即使是这种很不均衡的划分,最后计算出来的时间复杂度也是O(nlgn),具体的分析细节见《算法导论》

随机化快速排序

很显然我们希望,每次划分都尽量是均衡的,所以当待排序的数组是完全随机的时候,快速排序往往表现良好,每次递归划分都还比较均衡。但是我们往往不知道待排序的数组是个什么情况,所以我们可以将之前描述的快速排序稍加改进:

这里写图片描述

在每次递归划分的时候,我们随机生成作为piviot的那个数字,也就是A[i],i都是每次随机生成的p到r之间的一个数字,这样保证了每次划分都是随机的。

《算法导论》后边有快速排序的各种什么概率分析,这里略过了,以后再说。

原创粉丝点击