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

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

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

快速排序是一种常见的排序算法,它的基本思路是选取一个基准值,通过比较大小将数据分为两部分,然后分别对这两部分进行递归排序,最终得到一个有序序列。

算法流程

快速排序的核心操作是分区,以及递归排序。算法流程如下:

  1. 选取一个基准值,将数据分为两部分:比基准值小的在左边,比基准值大的在右边;
  2. 对左右两个部分分别进行递归排序,直到每个部分只剩下一个元素,或者是空序列。

具体实现可以使用挖坑填数或者左右指针交换两种方式,这里以挖坑填数为例进行介绍,算法流程如下:

  1. 选取第一个元素作为基准值;
  2. 定义两个指针 $i$ 和 $j$ ,分别从左右两侧开始扫描序列;
  3. 从右侧开始扫描,当扫描到的元素小于基准值时,停止扫描,并将该元素填到左侧的坑中;
  4. 从左侧开始扫描,当扫描到的元素大于基准值时,停止扫描,并将该元素填到右侧的坑中;
  5. 重复步骤 3 和步骤 4,直到 $i$ 和 $j$ 相遇;
  6. 将基准值填到相遇的坑中。
可视化实现

为了更好地理解快速排序算法,我们可以使用可视化工具来演示算法运行过程。这里使用 Python 语言进行实现,主要依赖于以下工具:

  • pygame:用于创建图形窗口、显示矩形、文本等;
  • numpy:用于生成随机数。

代码实现如下(需要安装以上依赖):

import pygame
import numpy as np

pygame.init()

# 定义颜色常量
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

# 窗口大小
WIDTH, HEIGHT = 800, 600
# 盒子大小
BOX_WIDTH, BOX_HEIGHT = 4, 4

# 创建窗口
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('快速排序')

# 随机生成数字序列
nums = np.random.randint(1, 250, (WIDTH // BOX_WIDTH,) )
# 定义排序区间
left, right = 0, len(nums) - 1
# 定义栈
stack = [(left, right)]

# 绘制序列
def draw(nums, index, color):
    for i, num in enumerate(nums):
        x = i * BOX_WIDTH
        w = BOX_WIDTH
        h = num * BOX_HEIGHT
        y = HEIGHT - h
        rect = pygame.Rect(x, y, w, h)
        if i == index:
            pygame.draw.rect(screen, color, rect)
        else:
            pygame.draw.rect(screen, WHITE, rect)
        pygame.draw.rect(screen, BLACK, rect, 1)

# 快速排序
def quick_sort(nums, left, right):
    if left >= right:
        return
    i, j = left, right
    # 基准值
    pivot = nums[left]
    # 挖坑填数
    while i < j:
        while i < j and nums[j] >= pivot:
            j -= 1
        nums[i] = nums[j]
        draw(nums, i, RED)
        pygame.display.flip()
        while i < j and nums[i] <= pivot:
            i += 1
        nums[j] = nums[i]
        draw(nums, j, RED)
        pygame.display.flip()
    nums[i] = pivot
    draw(nums, i, GREEN)
    pygame.display.flip()
    # 递归排序
    stack.append((left, i - 1))
    stack.append((i + 1, right))

# 主程序
while stack:
    left, right = stack.pop()
    quick_sort(nums, left, right)
    draw(nums, -1, BLUE)
    pygame.display.flip()

# 关闭窗口
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()

代码主要分为三部分:绘制数字序列、快速排序、主程序。其中绘制数字序列使用 pygame.Rect 类绘制矩形盒子,根据序列值的大小决定矩形盒子的高度,不同的颜色填充矩形盒子,以表示不同的状态。快速排序根据挖坑填数的思路进行实现,通过将左右两个指针逐步缩减,以达到排序的目的。在排序过程中,使用栈来进行递归处理。主程序则循环处理栈中的任务,直到任务全部完成。

效果展示

下面是程序运行的结果图:

效果展示