快速排序算法

196 阅读3分钟

快速排序(Quick Sort)是计算机科学中一种高效的排序算法,由英国计算机科学家托尼·霍尔(Tony Hoare)于1960年提出。它基于分治法(Divide and Conquer)策略来将一个序列分成较小和较大的两个子序列,然后递归地排序两个子序列。快速排序在平均情况下具有O(n log n)的时间复杂度,且常数因子较小,因此在实践中通常比其他O(n log n)算法更快。

快速排序的基本步骤

  1. 选择基准(Pivot Selection):从数组中选择一个元素作为基准值。选择的方法有多种,例如选择第一个元素、最后一个元素、中间的元素或随机选择一个元素。为了优化性能,可以采用“三数取中法”,即选取数组首尾和中间位置三个元素中的中位数作为基准。

  2. 分区(Partitioning):重新排列数组,使得所有比基准小的元素放在基准前面,所有比基准大的元素放在基准后面(相等的元素可以到任一边)。在这个过程结束后,该基准就位于其最终的位置。这个重要的操作称为分区操作。

  3. 递归调用:对基准左右两边的子数组分别进行递归调用快速排序。递归的基本条件是当子数组长度为0或1时停止递归,因为这样的数组已经是有序的。

  4. 合并结果:由于快速排序是原地排序算法,不需要像归并排序那样合并已经排序好的子数组,完成分区和递归调用后,整个数组就已经排好序了。

快速排序的实现

以下是使用Python编写的简单快速排序实现:

def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    else:
        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 forx in arr if x > pivot]
        return quick_sort(left) + middle + quick_sort(right)

# 示例调用
print(quick_sort([3,6,8,10,1,2,1]))

这段代码虽然简洁,但在实际应用中并不是最优的,因为它创建了额外的列表,增加了空间复杂度,并且对于含有大量重复元素的数据集效率较低。更优化的版本会直接在原始数组上进行操作,减少内存占用。

快速排序的优缺点

  • 优点:快速排序是原地排序,不需要额外的大规模存储空间;在大多数情况下,它的表现非常出色,时间复杂度接近理论上的最优O(n log n)。
  • 缺点:最坏情况下的时间复杂度为O(n^2),这发生在每次选择的基准都是最坏选择(如最小或最大元素),例如对已经排序的数组进行排序时。此外,快速排序是非稳定排序,意味着相同值的元素之间的相对顺序可能会改变。

通过引入随机化选择基准或者使用三数取中法,可以在很大程度上避免最坏情况的发生,使快速排序成为一种实用且高效的排序方法。