数据结构-堆

128 阅读3分钟

「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战

介绍

,这种 数据结构中,如果一上去就去了解它,那么需要花费很长时间,不过这里如果想理解快速理解 ,这里需要先了解一下,什么是 完全二叉树

完全二叉树

完全二叉树 之前在写的这篇文章 数据结构-树 简单说了下相关的 节点 分支 的东西,这里再细致说一下。

  • 首先符合 二叉树 的概念,每个节点 最多 包含两颗子树,子树有左右次序之分。

  • 第二,每个节点的生成顺序,只能是 从上到下从左到右,依次进行生成。下图就是一个 完全二叉树

    image.png

  • 这里列举几个 非 完全二叉树 的图,帮助理解。

image.png

image.png

堆 介绍

讲解完 完全二叉树,就好理解 了。

的每个节点的 父节点 一定要大于当前节点。或者说,父节点 的值,总是大于 两个孩子节点 的值。

这里还是用利用图进行讲解。

image.png

图中,A1~A8 对应的值放到数组中是 [20,15,3,7,9,2,1,6]。可以清楚的看到 每个父节点的值,总是大于两个子节点的。

问题

我们已经知道什么是 了,但是我们如何保证我们的数组,就是一个堆呢?又或者说,怎么让一个 非 堆 的数组,变成一个 数组 呢?

这里把上面的 数组 进行打乱,变成一个完全二叉树,如下图

image.png

这个二叉树的值为 [7,15,1,20,2,9,3,6],我们接下来就要将这个打乱后的数组 也就是将 完全二叉树 变成 结构

解决

  • 如何实现?

    肯定是进行交换。

  • 如何交换?从哪个位置开始?

    肯定是按照 广度优先遍历 得到的数据结果,按照从后往前开始进行遍历交换。

  • 公式

    这里有个几个计算公式,以 A4 为例,注意数组中A4的下标 为 3

    • A4 的 父节点是 A2

      A2 的下标 = Math.floor(A4的下标 - 1) / 2 = 1

    • A4 的 左孩子节点是 A8

      A8 的下标 = 2*A4的下标 + 1 = 7

    • A4 的 右孩子节点 暂时没有,但是公式是一直存在的

      A4 右孩子的下标 = 2*A4的下标 + 2 = 8

这里用图解进行直观说明

image.png

首先从 第四个 棕色 部分 开始交换(交换结果就是:最大值为父节点),交换后再更新相关下标,再循环交换。以此类推,然后从 第三个 粉色 部分,到 第二个 绿色 部分,到 第一个 蓝色 部分,依次交换完毕后,就得到 这个数据结构。

总结

这个 数据结构 的基本是 完全二叉树。下面是 结构的注意点。

  • 每个节点 最多 包含两颗子树,子树有左右次序之分。
  • 只能是 从上到下从左到右 依次进行生成。
  • 父节点 的值,总是大于 两个孩子节点 的值