STL堆与手写堆

本文介绍了堆的基本特点,包括插入、求最小值和删除最小值等操作。详细阐述了C++ STL中的小根堆,并指出其不支持直接删除和修改元素。接着讲解了手写堆的存储方式,通过一维数组实现,并详细描述了down和up操作,以及如何进行节点更新、插入、获取最小值、删除堆顶元素、删除任意元素和修改元素的操作。还提到了手写堆初始化的高效方法,通过从二叉树倒数第二层开始的down操作达到O(n)的时间复杂度。
摘要由CSDN通过智能技术生成

堆的特点

  1. 插入一个数;
  2. 求集合中的最小值;
  3. 删除最小值;

以上是堆的最基本的特性,C++ STL 实现的小根堆支持上述操作。

  1. 删除任意一个元素;
  2. 修改如意一个元素;

以上两个特性 STL 堆无法直接实现,但是可以间接实现。

堆是一个完全二叉树。

image-20201121185808479

以小根堆为例子,每个节点的值都小于等于两个子节点。所以根节点是集合的最小值。

STL 堆

STL 堆就是 优先队列。并且实现的堆是 小根堆

定义:

#include <queue>
typedef pair<int, int> PII;
priority_queue<PII, vector<PII>, greater<PII>> heap;

利用 pair 的 first 来排序。每次返回一个 pair。

插入一个数:heap.push({x, y})

获得堆的最小值:heap.top()

删除堆的最小值:heap.pop()

手写堆

手写堆的存储

手写堆时,直接使用一个一维数组来存储,因为堆是一个完全二叉树。

image-20201121190626282

根节点 heap[1]。

节点 x 的左儿子:2x

节点 x 的右儿子:2x + 1

**注意:下标从 0 开始。这是因为 0 的左儿子使用公式计算还是 0。**从 0 开始就不太方便了。

手写堆的两个基本操作

手写堆的所有功能都是通过这两个基本操作实现的:

down( x ) :将一个节点向上移。

up( x ) :将一个节点向下移。

down 与 up 都是与树的高度成正比的,所以时间复杂度 O ( l o g n ) O(logn) O(logn) 的。

const int N = 100010;

int n, m;
int heap[N], size;

void down(int u) {
   
    int t = u; // 用 t 存储三个节点(u 节点和它的两个子节点)中的最小值
    if (u * 2 <= size && h[u * 2] < h[t]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值