《征服数据结构》堆

摘要:

1,堆的介绍

2,堆中元素的添加

3,堆中元素的删除

4,堆的代码实现

5,堆排序中的建堆

1,堆的介绍

堆(Heap)是一种特殊的完全二叉树,堆中元素都有优先级,我们常说的优先队列(PriorityQueue)指的就是堆。

完全二叉树就是一棵二叉树除了最下面一层外,其它各层的节点数目均已达最大值,且最下面一层的所有节点从左向右连续紧密排列,这样的二叉树被称为完全二叉树。

如下图所示,第二个就不是完全二叉树,因为节点 3 有右子树没有左子树,最后一层不是从左往右紧密排列的。

10a9304b61645e36fe0093e1cfbbd710.png

堆一般分为两种,一种是最大堆(有的也叫大根堆,大顶堆),一种是最小堆。最大堆根节点的值是堆中最大的,最小堆根节点的值是堆中最小的。

两者原理差不多,这里只介绍其中一种,我们就拿最小堆来讲解。因为堆是一棵完全二叉树,所以如果知道子节点的下标,那么一定知道父节点的下标,如果知道父节点的下标也一定知道子节点的下标(假设有子节点)。

dddfd840e938dec6228e9da82b03c6f3.png

他们的对应关系如下:

父节点的下标 = (子节点下标-1) >> 1;
左子节点下标 = 父节点下标*2 + 1;
右子节点下标 = 父节点下标*2 + 2;

堆的常见函数如下,其中往堆中添加元素会往上调整,删除堆顶元素会往下调整,这个在下面添加和删除的时候都会有介绍。

public void add(int val);// 往堆中添加元素
public int poll();// 删除堆顶元素
public int peek();// 获取堆顶元素,不删除

2,堆中元素的添加

堆既是二叉树也是数组,添加元素的时候,按照数组的顺序添加,实际上相当于在完全二叉树中添加一个叶子节点。

de1c53e39d491a17e4d4d0b71822cd53.png

因为堆中元素是有优先级的,添加完之后还要根据优先级进行往上调整。就是和父节点比较谁的值小(这里介绍的是最小堆),如果比父节点小就和父节点交换,交换完之后,还要继续往上比较 …… ,如果比父节点值大就不在交换,如下图所示。

d103f409197e7e210261cc62e3f03137.png

这样通过不断的和父节点比较,如果添加的元素是堆中最小的,他最终会到根节点,也就是最小堆的根节点是堆中所有元素的最小值。如果添加元素不比父节点小,就不需要交换。

  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据结构和算法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值