欢迎访问宙启技术站
智能推送

快速排序算法:用Python编写的10个函数

发布时间:2023-05-28 11:37:10

快速排序(Quick Sort)是一种常用的高效排序算法。它的核心思想是分治法,通过将数组分成两部分,一部分比基准值小,一部分比基准值大,再对两部分分别进行排序,最终达到整个数组有序的目的。下面将介绍用Python编写的10个快速排序算法的函数。

1. 递归版快排

递归版的快排是快排算法的经典实现方式,其函数签名如下:

def quick_sort_recursive(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quick_sort_recursive(left) + middle + quick_sort_recursive(right)

2. 非递归版快排

非递归版的快排与递归版的实现方式略有不同,其函数签名如下:

def quick_sort_iterative(arr):
    if len(arr) <= 1:
        return arr
    stack = [(0, len(arr) - 1)]
    while stack:
        start, end = stack.pop()
        if start >= end:
            continue
        pivot = arr[(start + end) // 2]
        left, right = start, end
        while left <= right:
            while arr[left] < pivot:
                left += 1
            while arr[right] > pivot:
                right -= 1
            if left <= right:
                arr[left], arr[right] = arr[right], arr[left]
                left += 1
                right -= 1
        stack.append((start, right))
        stack.append((left, end))
    return arr

3. 随机化快排

在数据量较大的情况下,递归版快排的性能可能会受到影响。为了解决这个问题,我们可以使用随机化的快排算法。其函数签名如下:

import random

def quick_sort_randomized(arr):
    if len(arr) <= 1:
        return arr
    pivot = random.choice(arr)
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quick_sort_randomized(left) + middle + quick_sort_randomized(right)

4. 单向扫描快排

单向扫描快排(单边循环快排)是一种快速排序算法的变种,其函数签名如下:

def quick_sort_single(arr, low=0, high=None):
    if high is None:
        high = len(arr) - 1
    if low < high:
        pivot_index = partition_single(arr, low, high)
        quick_sort_single(arr, low, pivot_index)
        quick_sort_single(arr, pivot_index + 1, high)
    return arr

def partition_single(arr, low, high):
    pivot = arr[low]
    j = low
    for i in range(low + 1, high + 1):
        if arr[i] <= pivot:
            j += 1
            arr[j], arr[i] = arr[i], arr[j]
    arr[low], arr[j] = arr[j], arr[low]
    return j

5. 双向扫描快排

双向扫描快排(双边循环快排)是单向扫描快排的进一步变种,其函数签名如下:

def quick_sort_dual(arr, low=0, high=None):
    if high is None:
        high = len(arr) - 1
    if low < high:
        pivot_index = partition_dual(arr, low, high)
        quick_sort_dual(arr, low, pivot_index - 1)
        quick_sort_dual(arr, pivot_index + 1, high)
    return arr

def partition_dual(arr, low, high):
    pivot = arr[low]
    left, right = low + 1, high
    while True:
        while left <= right and arr[left] < pivot:
            left += 1
        while left <= right and arr[right] > pivot:
            right -= 1
        if left <= right:
            arr[left], arr[right] = arr[right], arr[left]
            left += 1
            right -= 1
        else:
            break
    arr[low], arr[right] = arr[right], arr[low]
    return right

6. 原地快排

原地快排是一种不需要额外空间的快速排序算法,其函数签名如下:

def quick_sort_inplace(arr, low=0, high=None):
    if high is None:
        high = len(arr) - 1
    if low < high:
        pivot_index = partition_inplace(arr, low, high)
        quick_sort_inplace(arr, low, pivot_index - 1)
        quick_sort_inplace(arr, pivot_index + 1, high)
    return arr

def partition_inplace(arr, low, high):
    pivot = arr[low]
    i, j = low, high
    while i < j:
        while i < j and arr[j] > pivot:
            j -= 1
        while i < j and arr[i] <= pivot:
            i += 1
        arr[i], arr[j] = arr[j], arr[i]
    arr[low], arr[j] = arr[j], arr[low]
    return j

7. 三向切分快排

三向切分快排是一种针对重复元素较多的情况的优化快排算法,其函数签名如下:

def quick_sort_3way(arr, low=0, high=None):
    if high is None:
        high = len(arr) - 1
    if low < high:
        lt, gt, i = partition_3way(arr, low, high)
        quick_sort_3way(arr, low, lt - 1)
        quick_sort_3way(arr, gt + 1, high)
    return arr

def partition_3way(arr, low, high):
    pivot = arr[low]
    lt, gt, i = low, high, low + 1
    while i <= gt:
        if arr[i] < pivot:
            arr[i], arr[lt] = arr[lt], arr[i]
            i += 1
            lt += 1
        elif arr[i] > pivot:
            arr[i], arr[gt] = arr[gt], arr[i]
            gt -= 1
        else:
            i += 1
    return lt, gt

8. 基数排序快排

基数排序快排结合了基数排序和快速排序的优点,其函数签名如下:

def quick_sort_radix(arr, radix=10):
    if len(arr) <= 1:
        return arr
    # 计算最大值和位数
    max_val, digits = max(arr), 1
    while max_val >= radix ** digits:
        digits += 1
    # 基数排序
    for i in range(digits):
        buckets = [[] for _ in range(radix)]
        for val in arr:
            digit = (val // (radix ** i)) % radix
            buckets[digit].append(val)
        arr = [val for bucket in buckets for val in bucket]
    # 递归调用快排
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quick_sort_radix(left) + middle + quick_sort_radix(right)

9. Lomuto快排

Lomuto快排是一种普遍认为不如Hoare快排的变体,但其实现简单易懂,其函数签名如下:

`

def quick_sort_lomuto(arr, low=0, high=None):

if high is None:

high = len(arr) - 1

if low < high:

pivot_index = partition_lomuto(arr, low, high)

quick_sort_lomuto(arr, low, pivot_index - 1)

quick_sort_lomuto(arr, pivot_index + 1, high)

return arr

def