其他分享
首页 > 其他分享> > 数据结构—完全二叉堆

数据结构—完全二叉堆

作者:互联网

1. 简介

2. 定义

以下以最小堆为例。

在这里插入图片描述

3. 插入

假设待插入的 entry 为 e e e。

(1)首先在堆尾之后的一个位置插入一个新节点,并存储 e e e;
(2)假设当前节点为 x x x(初始时, x . e n t r y = e x.entry=e x.entry=e),其父节点为 p p p;
(3)如果 p . e n t r y ≤ x . e n t r y p.entry \le x.entry p.entry≤x.entry,则成功返回;否则,
(4)上虑:如果 x . e n t r y < p . e n t r y x.entry \lt p.entry x.entry<p.entry,则令 x . e n t r y x.entry x.entry 和 p . e n t r y p.entry p.entry 互换位置,然后令 x x x 指向 p p p,令 p p p 指向 p p p 的父节点,接着回到步骤(3)。

4. 删除

待删除的 entry 总是位于堆顶。

(1)首先,交换堆顶和堆尾的 entry,然后将堆的大小减一(堆尾前移),以删除堆顶元素(被删除的元素位于堆尾之后的一个位置);
(2)令当前节点为 p p p(初始时, p p p 为堆顶);
(3)令 x x x 为 p p p 的两个孩子节点中较小的一个;
(4)如果 p . e n t r y ≤ x . e n t r y p.entry \le x.entry p.entry≤x.entry,则成功返回;否则,
(5)下虑:如果 x . e n t r y < p . e n t r y x.entry \lt p.entry x.entry<p.entry,则令 x . e n t r y x.entry x.entry 和 p . e n t r y p.entry p.entry 互换位置,然后令 p p p 指向 x x x,接着回到步骤(3)。

5. 建堆

如下图所示,假设 H 0 , H 1 H_0, H_1 H0​,H1​ 是两个最小堆,现欲将节点 p p p 和最小堆 H 0 , H 1 H_0,H_1 H0​,H1​ 合并为一个新的最小堆。

所需操作是:

(1)令 H 0 H_0 H0​ 为 p p p 的左孩子, H 1 H_1 H1​ 为 p p p 的右孩子;
(2)接着,从 p p p 开始执行下虑操作即可。

在这里插入图片描述
因此,给定一个数组,其大小为 n n n,现欲使用它构建一个最小堆所需的操作为:

(1)设当前节点为 x x x,其节点编号为 m m m,初始时, x x x 为堆的最后一个内部节点,编号为 m ← ⌊ ( n − 2 ) / 2 ⌋ m \leftarrow \lfloor (n-2)/2 \rfloor m←⌊(n−2)/2⌋;
(2)如果 m < 0 m \lt 0 m<0,则返回;否则,从 x x x 开始执行下虑操作(先将子树 x x x 转换为一个最小堆);
(3)接着将 x x x 指向前一个内部节点,其编号为 m ← m − 1 m \leftarrow m-1 m←m−1,然后回到步骤(2)。

上述建堆操作的时间复杂度为 O ( n ) O(n) O(n)。

6. 堆排序

总体而言,堆排序的过程为:对堆执行 n n n 次删除操作,因此其时间复杂度为 O ( n log ⁡ n ) O(n\log n) O(nlogn)。

因为每次删除操作都会将被删除的堆顶元素放到堆尾,而且堆的大小也在不断地减一(堆尾随之不断地向前移动),因此,最后的数组将包含排序后的元素。

对于最小堆来说,堆排序的直接结果是逆序的;而对于最大堆来说,则是顺序的。

标签:log,删除,最小,完全,二叉,编号,entry,数据结构,节点
来源: https://blog.csdn.net/gaoZhuanMing/article/details/121778116