快速排序(Quick Sort)同样是使用了分治法的思想,相比于其他的排序方法,它所用到的空间更少,因为其可以实现原地排序。同时如果随机选取中心枢(pivot),它也是一个随机算法。最重要的是,快速排序(Quick sort)的算法分析的过程非常给力。

本文首先描述问题,再说明快速排序(Quick Sort)的基本思路并给出伪代码,之后贴出自己的Python代码。在验证完算法的正确性之后,给出如何选择好的中心枢(pivot)的方法,即随机快速排序(Randomized Quick sort),并贴代码。最后进行算法复杂度分析。

问题描述

问题描述和其他排序算法一样,输入一组未排序的数组,如左边的数组,通过快速排序算法的计算,输出一组正确排序的数组,如右边的数组。

基础排序算法之快速排序(Quick Sort)


基本思路和伪代码

在给定的数组中选择一个元素作为中心枢(pivot),对数组重排列并分割(Partition),使得位于该中心枢(pivot)左边的元素都小于该元素,右边的元素都大于该元素,之后递归处理左右两组数。

这里值得注意的地方就是,每一次重排列之后,所选择的中心枢(pivot)元素所在的位置,就是最终排序结果中它应该在的位置。

1 QuickSort(array A, length n)
2     if n = 1 return
3     p = choosePivot(A, n)
4     Partition A around p
5     recursively sort 1st part
6     recursively sort 2st part

 

经过第4行的操作之后,位于左边的所有元素都小于p,而右边的数都大于p。下文中所有中心枢(pivot)元素都用p表示。

基础排序算法之快速排序(Quick Sort)

基于某一个p来对数组进行分块有两种实现的方法,第一种方法在内存在开辟新的数组,遍历元素组元素,小于p的从头插入数组,大于p的从尾部插入数组,给个例子:

基础排序算法之快速排序(Quick Sort)

而第二种方法是原地排序,比第一稍微复杂一点。假设p元素总在数组的最前端(不在最前端就让它和最前端的元素交换),将整个数组分为两部分,前半部分为已经和p比较过的元素集,后半部分为没有和p比较过的元素集。其中前半部分又分为小于p和大于p两部分。如图:

基础排序算法之快速排序(Quick Sort)

那么只要需要两个标记值i和j就可以所有部分分割开。i 标记小于p部分末端元素,j标记大于p部分的末端元素。如下例:基础排序算法之快速排序(Quick Sort)

分割(Partition)的伪代码:

Partition(A, l, r)       [input=A[l.......r]]
    p=A[l]
    i=l+1
    for j=l+1 to r
        if A[j]<p
            swap A[i] and A[j]
            i=i+1
    swap A[l] and A[i-1]

 

假设处理的数组长度为N,从伪代码中可以比较容易算出,Partition的时间复杂度为O(N),而且也实现了原地排序。

Python代码

Pivot选取首元素的实现

 1 import random
 2 
 3 def quick_sort(datalist,l,r):
 4     if l<r-1:
 5         q=partition_first(datalist,l,r)
 6         datalist=quick_sort(datalist,l,q)
 7         datalist=quick_sort(datalist,q+1,r)        
 8         return datalist
 9     else:
10         return datalist
11 
12 def partition_first(datalist,l,r):
13     p=datalist[l]
14     i=l+1
15     for j in range(l+1,r):
16         if datalist[j]<p:
17             datalist[i],datalist[j]=datalist[j],datalist[i]
18             i=i+1
19     datalist[l],datalist[i-1]=datalist[i-1],datalist[l]
20     return i-1
View Code

相关文章:

  • 2021-11-20
  • 2021-12-10
  • 2022-12-23
  • 2021-09-16
  • 2021-10-18
  • 2021-10-19
  • 2018-06-23
猜你喜欢
  • 2021-08-29
  • 2021-07-09
  • 2021-11-25
  • 2021-12-15
  • 2021-11-08
  • 2021-12-30
  • 2022-12-23
相关资源
相似解决方案