📜  排序算法可视化:快速排序(1)

📅  最后修改于: 2023-12-03 15:25:55.957000             🧑  作者: Mango

排序算法可视化:快速排序

快速排序是一种基于分治的排序算法,它的优势在于排序速度快,且占用的内存较少(不需要额外的内存空间)。

快速排序的流程

快速排序的流程分为以下几步:

  1. 首先在序列中选择一个基准(pivot)值。
  2. 把序列中比基准值小的元素放到基准值左边,比基准值大的元素放到基准值右边。这个过程被称为分区(partitioning)。
  3. 对左右两个分区重复上述步骤,直到所有分区只剩下一个元素。
快速排序的实现

快速排序的实现可以使用递归或非递归的方式,下面我们使用递归的方式来实现快速排序。

快速排序的实现代码如下:

def quick_sort(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(left) + middle + quick_sort(right) # 递归排序左右分区

arr = [3, 6, 2, 7, 1, 0, 9, 5, 8, 4]
print(quick_sort(arr)) # 输出 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
快速排序的可视化

为了更好地理解快速排序的过程,我们可以将它的过程可视化出来。

下面是快速排序的可视化代码(使用matplotlib绘制):

import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig, ax = plt.subplots()

def quicksort(arr, start, end):
    if start >= end:
        return
    pivot = arr[end] # 选择基准值
    i = start
    for j in range(start, end):
        if arr[j] < pivot: # 分区(小于基准值的元素放在左边)
            ax.bar(range(len(arr)), arr)
            arr[i], arr[j] = arr[j], arr[i]
            i += 1
        yield arr
    ax.bar(range(len(arr)), arr)
    arr[i], arr[end] = arr[end], arr[i] # 分区(大于基准值的元素放在右边)
    yield arr
    yield from quicksort(arr, start, i-1) # 递归排序左右分区
    yield from quicksort(arr, i+1, end)

arr = [3, 6, 2, 7, 1, 0, 9, 5, 8, 4]
generator = quicksort(arr, 0, len(arr)-1)

def animate(arr):
    ax.clear()
    ax.bar(range(len(arr)), arr)

ani = animation.FuncAnimation(fig, animate, frames=generator)
plt.show()

使用上述代码可以得到一个动态的可视化效果,可以更直观地理解快速排序的过程。

快速排序可视化动态效果

快速排序的时间复杂度

快速排序的时间复杂度为 $\mathcal{O}(n \log n)$,其中 $n$ 表示要排序的序列长度。快速排序的空间复杂度为 $\mathcal{O}(n)$,因为它不需要额外的内存空间来存储原始序列。