def quick_sort(arr, low, high):
# 选定枢纽元,并快速分派数组元素到枢纽元两侧
# 返回最终枢纽元位置索引
pivot_index = partition_arr(arr, low, high)
# 枢纽元左侧元素进行快速排序
if low < pivot_index - 1:
quick_sort(arr, low, pivot_index - 1)
# 枢纽元右侧元素进行快速排序
if pivot_index + 1 < high:
quick_sort(arr, pivot_index + 1, high)
# 随机选定枢纽元,然后快速将数组元素分派到枢纽元的两边
# 比枢纽元小的元素在左边,比枢纽元大的在右边
def partition_arr(arr, low, high):
# 随机选择枢纽元索引,避免算法复杂度退化成O(n^2)
selected_index = select_pivot_index(low, high)
# 枢纽元与最低位元素交换
swap_elem(arr, low, selected_index)
# 将枢纽元的值复制到变量pivot_elem, 此时,low位置留下一个坑位
pivot_elem = arr[low]
while low < high:
# 从右往左,依次将元素和枢纽元比较,直至找到比枢纽元小的元素,
# 将该元素【复制】到上次留下的坑位,此时坑位相当于转移到该元素索引位置
while low < high and pivot_elem <= arr[high]: #元素大小比较一定要有=
high = high - 1
arr[low] = arr[high]
# 从左往右,依次将元素和枢纽元比较,直至找到比枢纽元大的元素
# 将该元素【复制】到上次留下的坑位,此时坑位相当于转移到该元素索引位置
while low < high and pivot_elem >= arr[low]: #元素大小比较一定要有=
low = low + 1
arr[high] = arr[low]
# 上面的一个 <= 和 >= 保证在有重复的元素时,low和high也能不断靠近,
# 如果有重复元素的情况下,没有 = 来保障 low 和 high 是没有机会靠近直至相等的
# 退出while循环时,一定是确保 low = high 的
arr[low] = pivot_elem # 放入枢纽元素
return low
def select_pivot_index(low, high):
return random.randint(low, high)
def swap_elem(arr, index1, index2):
tmp = arr[index1]
arr[index1] = arr[index2]
arr[index2] = tmp