1. 算法介绍
快速排序(Quick Sort)分区交换排序(partition-exchange sort)快排
快速排序分治法(Divide and conquer)
基准(pivot)分区(partition)基准
2. Python实现
2.1 算法1
基准(pivot)列表生成式(List Comprehensions)
def quick_sort(L):
'''使用 '列表生成式(List Comprehensions)' 查找比 '基准(pivot)' 小或大的元素序列'''
n = len(L)
if n <= 1:
return L
pivot_value = L[0]
lesser = [item for item in L[1:] if item <= pivot_value]
greater = [item for item in L[1:] if item > pivot_value]
return quick_sort(lesser) + [pivot_value] + quick_sort(greater)
if __name__ == '__main__':
L1 = [54, 26, 93, 17, 77, 31, 44, 55, 20]
print('Before: ', L1)
sorted = quick_sort(L1)
print('After: ', sorted)
# Output:
Before: [54, 26, 93, 17, 77, 31, 44, 55, 20]
After: [17, 20, 26, 31, 44, 54, 55, 77, 93]
也可以将上述排序函数改写为一行:
quick_sort = lambda L: L if len(L) <= 1 else quick_sort([i for i in L[1:] if i <= L[0]]) + [L[0]] + quick_sort([j for j in L[1:] if j > L[0]])
测试通过:
quick_sort = lambda L: L if len(L) <= 1 else quick_sort([i for i in L[1:] if i <= L[0]]) + [L[0]] + quick_sort([j for j in L[1:] if j > L[0]])
if __name__ == '__main__':
L1 = [54, 26, 93, 17, 77, 31, 44, 55, 20]
print('Before: ', L1)
sorted = quick_sort(L1)
print('After: ', sorted)
# Output:
Before: [54, 26, 93, 17, 77, 31, 44, 55, 20]
After: [17, 20, 26, 31, 44, 54, 55, 77, 93]
压力测试:
from timeit import timeit
def test():
# import random
# gen = (random.randint(1, 100) for i in range(100)) # 产生100个 1-99 范围内的随机整数
# L = list(gen)
L = [96, 2, 65, 23, 47, 58, 8, 48, 69, 92, 34, 83, 93, 47, 45, 55, 95, 15, 92, 24, 64, 19, 29, 55, 35, 48, 39, 29, 63, 94, 99, 38, 50, 10, 10, 93, 74, 27, 74, 44, 29, 81, 85, 86, 74, 30, 50, 50, 12, 12, 38, 75, 41, 87, 80, 97, 16, 48, 65, 69, 83, 71, 28, 9, 64, 69, 27, 74, 74, 86, 40, 69, 79, 79, 77, 100, 53, 72, 77, 16, 8, 36, 41, 58, 59, 29, 46, 79, 81, 66, 8, 35, 60, 52, 2, 82, 2, 36, 79, 66]
quick_sort(L)
def quick_sort(L):
n = len(L)
if n <= 1:
return L
pivot_value = L[0]
lesser = [item for item in L[1:] if item <= pivot_value]
greater = [item for item in L[1:] if item > pivot_value]
return quick_sort(lesser) + [pivot_value] + quick_sort(greater)
print('Quick sort function run 1000 times, cost: ', timeit('test()', 'from __main__ import test', number=1000), 'seconds.')
# Output:
Quick sort function run 1000 times, cost: 0.2375717348850251 seconds.
2.2 算法2
def quick_sort(L, first, last):
'''使用 '递归(recursive)' 的方式,实现快速排序算法
first 和 last 都表示序列的下标
'''
if first < last: # 左、右子序列只剩一个元素时,退出递归 (first == last)
pivot_index = partition(L, first, last) # 返回 '基准' 值的最终正确位置的下标
quick_sort(L, first, pivot_index-1)
quick_sort(L, pivot_index+1, last)
def partition(L, first, last):
'''一次快速排序的分区过程,将选定的 '基准(pivot)' 放到正确的位置上,小于它的值都在它的左边,大于它的值都在它的右边
first 和 last 都表示序列的下标
'''
pivot_value = L[first] # 可以选择序列的第1个元素、中间元素或最后1个元素为 '基准' 值,这里选择第1个
leftmark = first + 1 # leftmark 游标从左向右查找比 '基准' 值大的元素
rightmark = last # rightmark 游标从右向左查找比 '基准' 值小的元素
done = False
while not done:
# 当 leftmark 找到比 '基准' 值大的元素后,停下来
while leftmark <= rightmark and L[leftmark] <= pivot_value:
leftmark = leftmark + 1