数据结构--堆的要点、实现以及建堆时间复杂度证明

要点总结

  1. 堆的两个要素:是完全二叉树并且父节点的值一定大于(大根堆)或小于(小根堆)它的左右孩子。所有的操作,仔细思考后会发现,都是为绕这两点在做功课。

 

  1. 构建时使用的基础数据结构,一般使用数组模拟完全二叉树,模拟方法:

1号元素即为根节点

对于一个编号为n的节点,其左子节点编号为 2n,其右子节点编号为 2n + 1,其父节点编号为 n // 2

如果总结点数为n,则序号大于n/2的节点都是叶子节点

要取最后一个叶子节点,直接取数组末尾元素即可

 

  1. 向堆中插入元素

先直接将元素插入到数组末尾(即完全二叉树的)

然后将其进行上浮操作,如果是小根堆,操作为:如果节点小于其父节点,则与父节点交换位置,此时节点位置将会上升(所以称为上浮)。重复操作至无法上浮。大根堆同理。


  1. 弹出堆顶元素

先直接移动最后一个元素去覆盖第一个元素

然后对此时的顶部元素进行下沉操作,如果是小根堆,操作为:如果当前节点没有比两个孩子节点都小,则将当前节点与左右孩子中的较小者交换(下沉)。重复操作至不能下沉

 

  1. 相关时间复杂度

单纯地取最小值,或者输出size。时间O(1),空间O(1)

插入删除操作。时间O(logn),空间O(1)

构造堆时有两种思路:如果是创建空堆并且一个一个插入,则时间复杂度为O(nlogn);但是其实可以优化,进行一个称之为堆化的操作,先将乱序的数组直接创建完全二叉树,然后自底向上,一层一层地进行类似下沉操作。时间复杂度:时间复杂度为O(n),详解如下

建堆详细时间复杂度证明

设整个堆的节点个数为 n a c t u a l n_{actual} nactual

在使用siftdown建堆时,鉴于最底层的节点时不需要操作的,我们将其剔除

所以需要操作的节点数为 2 k − 1 2^k-1 2k1, 其中 k = f l o o r ( l o g 2 n a c t u a l ) k = floor(log_2n_{actual}) k=floor(log2nactual),为了便于计算,我们令 n = 2 k n = 2^k n=2k

这样一来,我们要计算的部分变得十分规整,其中 n 2 n\over2 2n个节点最多向下操作一次, n 4 n\over4 4n个节点最多向下操作两次,依次类推

求和式可写为: S = 1 × n 2 + 2 × n 4 + 3 × n 8 + . . . + ( k − 1 ) × n 2 k − 1 + k × n 2 k S = 1 \times {n\over2} + 2 \times {n\over4} + 3 \times {n\over8} + ... + (k-1) \times {n\over2^{k-1}} + k \times {n\over2^k} S=1×2n+2×

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值