📅  最后修改于: 2023-12-03 15:25:55.934000             🧑  作者: Mango
堆排序是一种高效的排序算法,其核心是建立一个最大/最小堆,然后将堆顶元素与堆底元素交换,不断缩小堆的范围,直到整个序列有序。
堆是一种特殊的二叉树,它同时满足以下两个条件:
堆可以分为最大堆和最小堆,分别以最大值和最小值为堆顶。在堆排序中,我们需要用到的是最大堆,因为堆排序是将最大值不断放到末尾。
下面是使用Python实现的可视化堆排序算法。其中,使用了pygame
库进行可视化,每一次构建最大堆或交换堆顶元素都会更新界面。
import pygame
import random
def heapify(nums, n, i, screen, width, height):
largest = i
l = 2 * i + 1
r = 2 * i + 2
if l < n and nums[largest] < nums[l]:
largest = l
if r < n and nums[largest] < nums[r]:
largest = r
if largest != i:
nums[i], nums[largest] = nums[largest], nums[i]
draw(nums, screen, width, height)
heapify(nums, n, largest, screen, width, height)
def heap_sort(nums, screen, width, height):
n = len(nums)
for i in range(n//2 - 1, -1, -1):
heapify(nums, n, i, screen, width, height)
for i in range(n-1, 0, -1):
nums[0], nums[i] = nums[i], nums[0]
draw(nums, screen, width, height)
heapify(nums, i, 0, screen, width, height)
def draw(nums, screen, width, height):
screen.fill((255, 255, 255))
margin = 5
size = 10
for i, num in enumerate(nums):
x = i * size + margin
y = height - num * size
pygame.draw.rect(screen, (0, 0, 0), (x, y, size, num * size))
pygame.display.flip()
def main():
nums = [random.randint(1, 100) for _ in range(50)]
pygame.init()
size = width, height = 520, 400
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Heap Sort")
draw(nums, screen, width, height)
heap_sort(nums, screen, width, height)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
return
if __name__ == '__main__':
main()
时间复杂度:O(nlogn)
空间复杂度:O(1)
堆排序是一种不稳定的排序算法,实际应用中较少使用,但其对于最坏情况的表现比快排要好。在可视化实现中,可以看到每一次堆重构和交换都能够在界面上得到体现,方便我们理解算法的核心思想。