堆排序算法

堆排序算法是一种高效的排序算法,它利用了堆这种数据结构来实现排序。堆是一种完全二叉树,并且满足堆的性质:对于每个节点i,其父节点的值大于(或小于)其子节点的值。堆排序算法可以分为两个阶段:建立堆和排序。

建立堆

在建立堆的阶段,我们需要将待排序的数组构建成一个堆。在堆中,根节点是最大(或最小)的元素。我们可以通过从最后一个非叶子节点开始,自底向上地调整每个节点,使其满足堆的性质。

首先,我们定义一个函数heapify,用来调整某个节点以满足堆的性质。我们将其实现为一个递归函数,它首先找到当前节点的左子节点和右子节点中的最大值(或最小值),然后将当前节点与其交换。然后,递归地调用heapify函数来继续调整被交换的子节点。

def heapify(arr, n, i):
    largest = i
    left = 2 * i + 1
    right = 2 * i + 2

    # 找到左子节点和右子节点中的最大值(或最小值)
    if left < n and arr[left] > arr[largest]:
        largest = left
    if right < n and arr[right] > arr[largest]:
        largest = right

    # 如果最大值(或最小值)不是当前节点,则交换它们,并递归调整被交换的子节点
    if largest != i:
        arr[i], arr[largest] = arr[largest], arr[i]
        heapify(arr, n, largest)

接下来,我们定义一个函数build_heap,用来建立堆。它从最后一个非叶子节点开始,依次调用heapify函数来调整每个节点。

def build_heap(arr):
    n = len(arr)

    # 从最后一个非叶子节点开始调整
    for i in range(n // 2 - 1, -1, -1):
        heapify(arr, n, i)

排序

在建立堆之后,我们可以通过重复从堆中取出最大(或最小)值,并将其放置到已排序的部分中来实现排序。具体步骤如下:

  1. 将堆的根节点与最后一个元素交换;
  2. 从根节点开始调用heapify函数,将堆的大小减一,并调整堆;
  3. 重复步骤1和2,直到堆的大小为1。

下面是完整的堆排序算法的实现:

def heap_sort(arr):
    n = len(arr)

    # 建立堆
    build_heap(arr)

    # 重复从堆中取出最大值,并将其放置到已排序的部分中
    for i in range(n - 1, 0, -1):
        arr[i], arr[0] = arr[0], arr[i]
        heapify(arr, i, 0)

示例

假设我们有一个待排序的数组[4, 2, 9, 6, 5],我们可以使用堆排序算法来排序它。

首先,我们建立堆:

arr = [4, 2, 9, 6, 5]
build_heap(arr)
print(arr)  # 输出:[9, 6, 4, 2, 5]

然后,我们进行排序:

heap_sort(arr)
print(arr)  # 输出:[2, 4, 5, 6, 9]

通过以上示例,我们可以看到,使用堆排序算法可以将一个无序的数组按照升序(或降序)进行排序。

堆排序算法的时间复杂度为O(nlogn),其中n是数组的长度。由于堆排序算法是原地排序算法,它不需要额外的空间来存储临时变量,因此空间复杂度为O(1)。

总结起来,堆排序算法是一种