算法10-10,10-11:二叉堆vector实现详解(C++代码)(小白向)

本文介绍了二叉堆的概念,包括小根堆和大根堆的特性。在小根堆中,每个节点都小于其子节点。文章详细阐述了小根堆的插入、删除操作,并提供了C++实现的小根堆模板。讨论了完全二叉树的性质在实现中的应用,以及如何利用这些性质优化插入和删除操作。此外,还提供了可视化资源帮助理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在阅读这篇题解之前,你需要明白完全二叉树的概念,百度一下

二叉堆是一种寻找最大值最小值十分高效的数据结构。

理论

普通二叉堆主要分为两种:

  • 小根堆
  • 大根堆

特性:二叉堆的每一个节点都比它的子节点大(大根堆)或小(小根堆)。

时间复杂度:插入删除为logn,去最大最小为常数。

为了保持这个特性,我们需要在插入删除时互换节点。

插入(小根堆)
  1. 将节点插入到最后一个位置。
  2. 与双亲节点比较,如果比上一个节点小就互换。
  3. 重复2,直到双亲节点比节点小,或者节点位于根节点。
删除(小根堆)

删除默认都是删除堆的根节点。

  1. 删除根节点。
  2. 使用最后一个节点来补根节点的位置。
  3. 与子节点互换调整,保持特性。应该选择左右节点中小的来换。
小灰的文章
可视化

实现

在实现之前,我们来复习下完全二叉树的性质:

如果对一棵有n个结点的完全二叉树的结点按层序编号, 则对任一结点i (1≤i≤n) 有:

  • 如果i=1, 则结点i是二叉树的根, 无双亲;如果i>1, 则其双亲节点是结点i/2
  • 如果2i>n, 则结点i无左孩子, 否则其左孩子是结点2i;
  • 如果2i+1>n, 则结点i无右孩子, 否则其右孩子是结点2i+1.

由于我们每一次插入和删除,都是在堆的最后一个节点的位置调整的,所以整个堆可以填充整个数据(不会出现稀疏状况),使用完全二叉树的特性可以快速定位双亲节点和子节点,所以,使用vector不会浪费空间

但是vector互换节点的速度并不快,可以考虑用一个临时变量存储,直到找到一个合适的节点,只进行一次互换(见我的代码)

我的实现 (小根堆)
//
// Created by Cat-shao on 2021/1/15.
// 小根堆模板
#include <vector>
using namespace std;
template<typename T>
class heap // 小根堆模板
{
   
   
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值