算法描述:
执行过程中,i 之前(含)的元素都比 A[r] 小,之后的比 A[r] 大。即 p ~ i 的元素比 A[r] 小,其后A[i+1] ~ A[j-1] 的元素比A[r]大。最后,交换A[i+1]与A[r]。
算法实现:
def QuickSort(a, p, r):
if p < r:
q = Partition(a, p, r)
QuickSort(a, p, q-1)
QuickSort(a, q+1, r)
def Partition(a, p, r):
x = a[r]
i = p-1
for j in range(p, r):
if a[j] <= x:
i += 1
a[i], a[j] = a[j], a[i]
a[i+1], a[r] = a[r], a[i+1]
return i+1
def main():
a = [2, 8, 7, 1, 3, 5, 6, 4]
QuickSort(a, 0, len(a)-1)
print(a)
if __name__=='__main__':
main()
随机化版本:
import numpy as np
import time
def RandomizedQuickSort(a, p, r):
if p < r:
q = RandomizedPartition(a, p, r)
RandomizedQuickSort(a, p, q-1)
RandomizedQuickSort(a, q+1, r)
def Partition(a, p, r):
x = a[r]
i = p-1
for j in range(p, r):
if a[j] <= x:
i += 1
a[i], a[j] = a[j], a[i]
a[i+1], a[r] = a[r], a[i+1]
return i+1
def RandomizedPartition(a, p, r):
import random
i = random.randint(p, r) # 随机选取一个元素作为主元
a[i], a[r] = a[r], a[i]
return Partition(a, p, r)
def main():
a = np.random.randint(low=0, high=1000, size=1000) # 随机生成1000个0到1000之间的整数并存到列表中
a = list(a)
before = time.time()
RandomizedQuickSort(a, 0, len(a)-1)
after = time.time()
operation_time = after - before # 计算运行时间
print("快速排序运算时间:", operation_time, "s")
# 快速排序时间复杂度为O(n*logn)
if __name__=='__main__':
main()
结果如下:
快速排序运算时间: 0.005533695220947266 s
期望为线性时间的选择算法:
from randomized_quicksort import RandomizedPartition
def RandomizedSelect(a, p, r, i):
if p == r:
return a[p]
q = RandomizedPartition(a, p, r) # 将数组划分为两个子数组A[p..q-1]和A[q+1..r]
k = q-p+1 # 计算子数组A[p..q]内的元素个数k
if i == k:
return a[q]
elif i < k:
return RandomizedSelect(a, p, q-1, i)
else:
return RandomizedSelect(a, q+1, r, i-k)
def main():
a = [2, 8, 7, 1, 3, 5, 6, 4]
print(RandomizedSelect(a, 0, len(a)-1, 4))
if __name__=='__main__':
main()
输出为第4小的数:4