描述
快速排序是一种基于分治策略的排序方法。对n个数组排序,最坏情况的运行时间为
O(n2)
,期望的运行时间为
O(nlg(n))
,由于其平均性能较好,通常用于排序的最佳的使用选择。
分治策略是一类算法设计的技术,把问题分成若干部分,递归求解每一部分的解,然后合并解集合构成全局解。
对于数组
A[p...r]
:
- 分解,划分数组为
A[p...q−1]
和
A[q+1...r]
,
其中 A[p...q−1] 每个元素都 <=A(q) <script type="math/tex" id="MathJax-Element-502"><=A(q)</script>, A[q+1...r] 每个元素都 >=A(q) 。 - 解决,递归,对子数组 A[p...q−1] 和 A[q+1...r] 分别进行排序。
- 合并
伪代码
quicksort(A, p, r)
if p < r
q = partition(A, q, r)
quicksort(A, p, q - 1)
quicksort(A, q + 1, r)
举例与代码
下面以例子说明partition函数实现。
例如数组A[13, 19, 9, 5, 12, 8, 7, 4, 21, 2, 6, 1]。
设定基准值,一般取第一项,这里为13。
就地排序,设法使13左侧的值都小于或等于13,13右侧的值都大于或等于13。
返回13最终所在位置,即q。
下面是一种实现方法:
def partition(A, p, r):
i = p
j = r
key = A[i]
while(i < j):
while (i < j and A[j] >= key):
j = j - 1
A[i] = A[j]
while (i < j and A[i] <= key):
i = i + 1
A[j] = A[i]
j = j - 1
A[i] = key
return i
每次迭代结果如下:
[q:9 p:0 r:11] [1, 6, 9, 5, 12, 8, 7, 4, 2, 13, 21, 19]
[q:0 p:0 r:8] [1, 6, 9, 5, 12, 8, 7, 4, 2, 13, 21, 19]
[q:4 p:1 r:8] [1, 2, 4, 5, 6, 8, 7, 12, 9, 13, 21, 19]
[q:1 p:1 r:3] [1, 2, 4, 5, 6, 8, 7, 12, 9, 13, 21, 19]
[q:2 p:2 r:3] [1, 2, 4, 5, 6, 8, 7, 12, 9, 13, 21, 19]
[q:6 p:5 r:8] [1, 2, 4, 5, 6, 7, 8, 12, 9, 13, 21, 19]
[q:8 p:7 r:8] [1, 2, 4, 5, 6, 7, 8, 9, 12, 13, 21, 19]
[q:11 p:10 r:11] [1, 2, 4, 5, 6, 7, 8, 9, 12, 13, 19, 21]
算法导论中实现方式如下:
def EXCHAGE(A, i, j):
if (A[i] == A[j]):
return
A[i] = A[i] ^ A[j]
A[j] = A[i] ^ A[j]
A[i] = A[i] ^ A[j]
def partition_(A, p, r):
key = A[r]
i = p - 1
for j in range(p, r):
if A[j] <= key:
i = i + 1
EXCHAGE(A, i, j)
EXCHAGE(A, i + 1, r)
return i + 1
运行时间比较
import numpy as np
import time as t
array = np.random.randint(1000000, size=100000)
def quicksort(A, p, r):
if (p >= r):
return
q = partition(array, p, r)
quicksort(A, p, q - 1)
quicksort(A, q + 1, r)
t_s = t.time()
quicksort(array, 0, len(array) - 1)
print((t.time() - t_s) * 1000)
partition耗时504.5ms
partition_耗时1174.6ms