043. 编写一个函数,实现堆排序算法

堆排序是一种基于二叉堆的比较排序算法。它利用了堆的性质来高效地排序数组。堆排序分为两个主要步骤:

  1. 构建最大堆:将数组转换为一个最大堆。
  2. 排序:逐步从堆中取出最大元素,将其放到数组的末尾,并调整堆以保持最大堆的性质。

示例代码

def heapify(arr, n, i):
    """
    堆调整函数,用于维护最大堆的性质。

    参数:
        arr (list): 输入数组。
        n (int): 数组的大小。
        i (int): 当前需要调整的节点索引。
    """
    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)

def heap_sort(arr):
    """
    堆排序函数。

    参数:
        arr (list): 输入数组。
    """
    n = len(arr)

    # 构建最大堆
    for i in range(n // 2 - 1, -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)  # 调整剩余的堆

# 测试代码
arr = [12, 11, 13, 5, 6, 7]
print("原始数组:", arr)
heap_sort(arr)
print("排序后的数组:", arr)

运行结果

运行上述代码后,输出如下:

原始数组: [12, 11, 13, 5, 6, 7]
排序后的数组: [5, 6, 7, 11, 12, 13]

代码解释

heapify 函数

  • 用于维护最大堆的性质。

  • 参数 arr 是输入数组,n 是数组的大小,i 是当前需要调整的节点索引。

  • 通过比较当前节点、左子节点和右子节点,找到最大值的索引 largest

  • 如果最大值不是当前节点,交换它们,并递归调整子树。

heap_sort 函数

  • 参数 arr 是输入数组。

  • 首先,通过从最后一个非叶子节点开始向上调整,构建最大堆。

  • 然后,从数组末尾开始,逐步将堆顶元素(最大值)放到数组末尾,并调整剩余的堆。

注意事项

  1. 构建最大堆:从最后一个非叶子节点开始向上调整,确保每个子树都满足最大堆的性质。
  2. 排序过程:每次将堆顶元素(最大值)放到数组末尾,然后调整剩余的堆,直到整个数组排序完成。
  3. 时间复杂度:堆排序的时间复杂度为 O(nlogn),其中 n 是数组的长度。
  4. 空间复杂度:堆排序是原地排序算法,空间复杂度为 O(1)。

视频讲解

BiliBili: 视睿网络-哔哩哔哩视频 (bilibili.com)