python实现堆排序的实例讲解

1. 什么是堆排序

堆排序是一种常见的排序算法,其思想是将待排序的数组构建成一棵完全二叉树,并将其转化为一个大(小)根堆,然后进行堆顶元素和末尾元素的交换,重新调整堆的结构,重复此过程直至排序完成。

堆排序的时间复杂度为O(nlogn),空间复杂度为O(1),因此被广泛应用于海量数据的排序中。

2. Python实现堆排序

2.1 实现思路

我们可以将堆分为两类:最大堆和最小堆。

最大堆:父节点的值大于等于它的子节点的值。

最小堆:父节点的值小于等于它的子节点的值。

对于大根堆来说,堆顶元素一定是最大的值,对于小根堆来说,堆顶元素一定是最小的值。因此我们可以通过将待排序数组构建成一个大根堆,然后将堆顶元素和末尾元素进行交换,然后剔除末尾元素,重新调整堆的结构,重复此过程直至排序完成。

2.2 代码实现

def heapify(arr, n, i):

largest = i

l = 2*i + 1

r = 2*i + 2

if l < n and arr[i] < arr[l]:

largest = l

if r < n and arr[largest] < arr[r]:

largest = r

if largest != i:

arr[i], arr[largest] = arr[largest], arr[i]

heapify(arr, n, largest)

def heap_sort(arr):

n = len(arr)

for i in range(n, -1, -1):

heapify(arr, n, i)

for i in range(n-1, 0, -1):

arr[i], arr[0] = arr[0], arr[i]

heapify(arr, i, 0)

2.3 代码解析

首先我们需要定义一个堆化函数heapify(arr, n, i),它的作用是将以i为父节点的子树(最多包括其子孙节点)进行堆调整。在堆调整的过程中,我们需要比较当前节点和其左右子节点的大小,然后交换当前节点和子节点,持续执行这一过程直至调整完成。

在堆排序过程中,我们需要先将待排序数组构建成一个大根堆。我们可以根据二叉树的性质得知,最后一个非叶子节点的下标为(n/2)-1,因此我们可以从最后一个非叶子节点开始,对所有节点进行堆调整。实现如下:

for i in range(n, -1, -1):

heapify(arr, n, i)

堆排序过程中,我们首先需要将堆顶元素和末尾元素进行交换,然后将剩余的元素进行堆调整。对于剩余的元素,我们只需要考虑其前i个元素,因为i+1到n-1都是已经排好序的。实现如下:

for i in range(n-1, 0, -1):

arr[i], arr[0] = arr[0], arr[i]

heapify(arr, i, 0)

2.4 测试代码

arr = [12, 11, 13, 5, 6, 7]

heap_sort(arr)

print("排序后的数组为:", end=" ")

for i in range(len(arr)):

print("%d" % arr[i], end=" ")

输出结果如下:

排序后的数组为: 5 6 7 11 12 13

3. 总结

堆排序是一种高效的排序算法,其时间复杂度为O(nlogn),空间复杂度为O(1)。Python实现堆排的代码相对简单,只需要定义一个堆化函数即可。编写堆排序代码时需要注意一些细节,如何构建堆、如何进行堆调整等。因此我们需要在理解其原理的基础上,多加实践,才能达到熟练掌握的程度。

后端开发标签