返回

**kiner 的算法刷题记 (5):Heap 与优先队列(数据结构基础篇)**

前端

完全二叉树的回顾

在上一篇文章中,我们讨论了完全二叉树的一些基本概念。完全二叉树是一种特殊的二叉树,它具有以下特性:

  • 除了最后一层之外,每一层都是完全填充的。
  • 最后一层的节点都集中在最左边。

堆的基本原理

Heap 是一种特殊的完全二叉树,其满足以下附加性质:

  • 堆序性质: 对于每个节点及其子节点,父节点的值始终大于或等于子节点的值(对于最小堆)或小于或等于子节点的值(对于最大堆)。

Heap 的类型

有两种主要类型的 Heap:

  • 最小堆: 根节点包含最小的值,每个父节点的值都大于或等于其子节点。
  • 最大堆: 根节点包含最大的值,每个父节点的值都小于或等于其子节点。

Heap 的操作

常见用于 Heap 的操作包括:

  • 插入: 将一个元素插入 Heap,同时保持堆序性质。
  • 删除: 从 Heap 中删除根节点,同时保持堆序性质。
  • 查找: 查找 Heap 中的最小(或最大)值。

优先队列

优先队列是一种数据结构,其遵循以下规则:

  • 元素被分配一个优先级。
  • 优先级最高的元素始终处于队列的开头。

Heap 通常被用来实现优先队列,因为它们可以在对数时间复杂度内执行插入、删除和查找操作。

应用:堆排序

堆排序是一种使用 Heap 进行排序的算法。其步骤如下:

  1. 将输入数组构建成一个 Heap。
  2. 重复以下步骤:
    • 从 Heap 中删除根节点(最小或最大值)。
    • 将根节点添加到输出数组。
    • 重新调整剩余的 Heap 以保持堆序性质。

示例和代码

为了进一步理解 Heap 和优先队列,我们来看一个示例。

考虑一个最小堆,其中元素的值为 [4, 2, 9, 7, 5, 8]。以下是如何将数组构建成一个最小堆:

        2
       / \
      4   9
     / \   \
    7   5   8

要从这个最小堆中删除根节点(2),我们可以按照以下步骤操作:

  1. 将最后一个元素(8)移动到根节点的位置。
  2. 将新根节点与它的子节点(4 和 7)进行比较。
  3. 将 4 移到 8 的位置,将 8 移到 7 的位置。
  4. 重复步骤 2-3,直到新根节点位于其正确的位置。

最终,最小堆变为:

        4
       / \
      7   9
     / \   \
    2   5   8

结论

Heap 和优先队列是数据结构中重要的概念,它们在各种应用中都有广泛的应用。通过理解它们的特性和操作,我们可以有效地使用它们来解决实际问题。