📜  堆排序算法(1)

📅  最后修改于: 2023-12-03 14:51:37.752000             🧑  作者: Mango

堆排序算法

堆排序算法是一种高效的排序算法。它的时间复杂度为 O(nlogn),其中 n 是待排序数组的长度。堆排序算法是基于二叉堆数据结构实现的。

二叉堆

二叉堆是一种特殊的二叉树,它满足两个性质:

  • 堆序性质:对于每个节点 i,它的父节点 j 的值不大于 i 的值(最大堆)或不小于 i 的值(最小堆)。
  • 完全二叉树性质:对于深度为 k 的节点,如果其左子树为空,则其右子树也必须为空。

二叉堆可以用数组来表示。假设二叉堆的根节点为第一个元素,那么左子节点为第二个元素,右子节点为第三个元素,以此类推。节点 i 的父节点为 i/2,左子节点为 2i,右子节点为 2i+1。

堆排序算法思路

堆排序算法的主要思路是:

  1. 将待排序的数组建立为一个最大堆。
  2. 将最大堆的根节点与最后一个节点交换。这样,最大值就被固定在数组的末尾了。
  3. 忽略最后一个节点(已经固定了最大值),将前面的元素重新构建为一个最大堆。
  4. 重复步骤 2 和 3,直到所有元素都被固定在正确的位置。
堆排序算法实现
建立最大堆

建立最大堆可以用自底向上的方式进行。假设数组的长度为 n,则从最后一个有子节点的节点开始,将其与其子节点比较,将较大值的节点作为父节点。将父节点与其自身的父节点比较,重复此过程,直到根节点。

def build_max_heap(arr):
    n = len(arr)
    for i in range(n//2, -1, -1):  # 从最后一个有子节点的节点开始
        heapify(arr, i)

def heapify(arr, i):
    left = 2 * i + 1
    right = 2 * i + 2
    largest = i
    if left < len(arr) and arr[left] > arr[largest]:
        largest = left
    if right < len(arr) and arr[right] > arr[largest]:
        largest = right
    if largest != i:
        arr[i], arr[largest] = arr[largest], arr[i]
        heapify(arr, largest)
堆排序

堆排序的主要实现思路是重复从最大堆中取出根节点(最大值),交换根节点和最后一个未排序的节点,然后将前面的元素重新构建为最大堆。

def heap_sort(arr):
    build_max_heap(arr)
    n = len(arr)
    for i in range(n-1, 0, -1):
        arr[0], arr[i] = arr[i], arr[0]
        heapify(arr[:i], 0)
总结

堆排序算法是一种高效的排序算法,其时间复杂度为 O(nlogn)。堆排序的思路是先将待排序数组构建为最大堆,然后重复从最大堆中取出根节点,将其交换到数组末尾。最后再将前面的元素重新构建为最大堆。堆排序算法的实现可以分为两个函数,一个用于建立最大堆,一个用于执行堆排序。