堆与优先队列基础知识

152 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 2 天,点击查看活动详情

堆的基础知识

可以简单理解成他是基于完全二叉树的一种结构。

大顶堆与小顶堆

  1. 大顶堆: 任意三元组之间,父节点都要大于两个子节点
  • 最大值:堆顶元素(所有节点的祖先)
  • 第二大值:根节点的左子节点或右子节点
  • 第三大值:意味着一定会有两个值大于它,在第二层或者第三层 只有父子节点之间有明确的大小关系,兄弟之间是没有明确的大小关系的

image.png

  1. 小顶堆:任意三元组之间,父节点都要小于两个子节点
  • 最小值:根节点

堆-尾部插入调整

在最后一层的最左侧新增一个节点 == 在数组的末尾新加一个元素

看插入的节点性质是否符合堆的性质 大顶堆中:如果新增的节点大于其父节点,那么就相互替换,直到符合其性质。--- 向上调整

如下图:实现在堆尾插入一个值为13的节点 image.png

image.png

image.png

image.png

ps: 数据结构:结构定义+结构操作,定义一种性质,并且维护这种性质

堆-头部弹出调整

弹出的是堆顶元素,这时需要用尾部元素补空,然后向下调整节点,使得整个堆满足其性质。

向下调整:当前根节点是否是所在三元组中最大的一个,如果不是就与其最大的那一个替换位置,直至符合性质要求。

堆排序

如:对一个数组中的所有元素从小到大排序?

  • 先对这个数组的元素进行建堆,建立成一个大顶堆
  • 进行 n 轮弹堆操作
    1. 每次堆顶元素与堆尾元素互换位置(弹出操作:堆顶弹出,堆尾补空;只不过这个把弹出的堆顶元素放到了数组的倒数第n位)
    2. 然后对堆尾元素做向下调整(调整成合法的大顶堆)
    3. 这时刚刚弹出的这个堆顶元素所在的最后一位,其实就不属于这个堆的合法位置了,但是他还属于数组的有效空间

image.png

口诀:
1、将堆顶元素与堆尾元素交换
2、将此操作看做是堆顶元素弹出操作
3、按照头部弹出以后的策略调整堆

堆-优先队列

严谨来说,优先队列是用堆来实现的

image.png

堆是优先队列的一种实现方式