堆(数据结构)

看视频做的笔记
【从堆的定义到优先队列、堆排序】 10分钟看懂必考的数据结构——堆 B站UP:工程部老周

堆的定义

堆必须是一个完全二叉树

完全二叉树

只允许最后一行不为满,且最后一行必须从左往右排序,元素之间不可以有间隔。

堆序性

大根堆

大根堆中,每个 父节点 元素都必须大于他的 子节点 元素
image

小根堆

小根堆中,每个父节点元素都必须小于他的子节点元素
image

堆的存储

首先按照层序遍历的顺序给节点编号,从上到下,从左到右,
把编号对应到一个数组的下标,然后把数存入到相应的下标里,(因为堆是完全二叉树,元素中间没有间隔,所以下标和位置编号是一一对应的)这样,一个堆就可以用一个一维数组来描述。
image

image

堆的基本操作

上滤和下滤

上滤

节点从下向上调整的操作。
例子:下图是一棵树,以大根堆为例。可以观察到只有最后一个元素破坏了堆序性,而部分都满足堆序性。
image
让它和它的父元素进行比较,如果它比父节点大,则交换,直到无法上移为止。

这个操作主要用于插入新元素到堆中。
image

下滤

根节点从上向下调整的过程叫做下滤
例子: 下图是一棵树,以大根堆为例。可以观察到只有树的根元素不符合堆序性,而下面的部分满足堆序性。

image

将破坏堆序性的元素和它的最大子节点比较,
如果小于它的最大子节点,则与之交换。
持续比较、交换,直到该元素大于它的子节点为止,或者移动到底部为止。
此时该树就成功地被调整成一个大根堆。
image

如果有一个乱序的数组,如何操作才能把它转化成堆呢?

有两种建堆的方法,分别对应上滤和下滤操作。

自顶向下 建堆法

方法:1、插入堆, 2、上滤
将新元素一个插入到堆的最后一位,然后对其进行上滤操作。

自下而上 建堆法

方法:对每个父节点进行下滤
复杂度为 O(N)

堆的具体应用

优先队列

优先队列有两个操作:
插入队列,弹出最小元素

弹出最小元素可以用 小根堆 来实现,因为小根堆的 根节点 本来就是最小元素,所以直接弹出 根节点 即可完成弹出操作,弹出后要将剩下的元素,调转成堆。 方法很简单:讲最后一个元素放到根节点,然后进行下滤操作即可。
所以弹出的复杂度为 O(logN).

堆排序

将优先队列的所有元素,依次弹出。
但实际上考虑到空间复杂度,排序的结果会存放到堆空缺的单元里。

完善后堆排序的过程:
用大根堆做堆排序(从小到大),
用小根堆做排序是倒序的
堆排序的复杂对为O(NlogN)
image

posted @ 2022-04-18 17:12  专心Coding的程侠  阅读(227)  评论(0编辑  收藏  举报