堆和STL —— priority_queue 【复习笔记】

embedded/2025/3/2 0:57:54/

1.

1.1 的定义

是一棵特殊的完全二叉树,可以实现优先级队列(priority queue),中每个结点,如果存在子树,那结点的权值要大于等于(小于等于)子树的所有结点的权值

可以分为大根:结点权值大于等于子树所有结点的权值

                  小根结点权值小于等于子树所有结点的权值

1.2 的存储

因为是一棵完全二叉树,而对于完全二叉树和满二叉树,可以使用数组来顺序存储。(二叉树的概念和静态实现 【复习笔记】-CSDN博客)

如果结点下标为 i (根结点从编号1开始):

(如果下列结点存在)

1. 父节点下标 为 i / 2;

2. 左孩子下标为 i * 2;

3. 右孩子下标为 i * 2 + 1;

的逻辑实现是完全二叉树,但存储实现是数组,如果要实现结构,要对数组进行一些调整

1.3 调整方法

1.3.1 向下调整法

 实现方法:1. 新添加的叶子节点和父节点权值比较,如果比它大(小),就交换

                   2. 交换后,重复过程1,直到节点比父亲节点权值小(大),或到达根节点的位置

#include<iostream>
using namespace std;int n;
const int N = 1e6;
int heap[N];//大根向上调整(小根改变大小判断即可)
void up(int child)
{int father = child / 2;//父节点存在,节点权值大于父节点while (father >= 1 && heap[father] < heap[child]){swap(heap[father], heap[child]);//调整关系,重复过程child = father;father = child;}
}//因为比较次数最差为树高,时间复杂度为O(log N)

1.3.2 向下调整法

实现方法:1. 找到左、右孩子中权值最大(小)的那个,如果比自己权值小,就交换

                  2. 重复过程1,直到换到叶子节点,或孩子节点的权值都比自己权值小(大)

#include<iostream>
using namespace std;int n;//标记大小
const int N = 1e6 + 10;
int heap[N];//大根向下调整
void down(int father)
{//找到左孩子节点int child = father * 2;//如果左孩子节点存在while (child<=n){//找到孩子节点中最大的if (child+1 <=n && heap[child] < heap[child + 1]) child += 1;if (heap[child] <= heap[father]) return;swap(heap[child], heap[father]);//重复该过程father = child;child = father * 2;}
}//因为比较次数最差为树高,时间复杂度为O(log N)

1.4 的实现

以下实现只是为了对进行模拟,会存在一些bug:为空还删除元素的情况未考虑(这需要自己判断是否为空,再进行删除)......

#include<iostream>
using namespace std;const int N = 1e6 + 10;
int n;
int heap[N];//默认大根void up(int child)
{int parent = child / 2;while (parent >= 1 && heap[child] > heap[parent]){swap(heap[parent], heap[child]);child = parent;parent = child / 2;}
}void down(int parent)
{int child = parent * 2;while (child <= n){if (child + 1 <= n && heap[child] < heap[child + 1])child++;if (heap[child] <= heap[parent]) return;swap(heap[child], heap[parent]);parent = child;child = parent * 2;}
}//插入,时间复杂度O(log N)
void push(int x)
{//根节点编号从1开始heap[++n] = x;//向上调整up(x);
}//删除,时间复杂度O(log N)
void pop()
{//先交换删除顶元素,再调整swap(heap[n--], heap[1]);//向下调整down(1);
}//返回顶元素,时间复杂度O(1)
int top()
{return heap[1];
}//返回大小,时间复杂度O(1)
int size()
{return n;
}//测试
int main()
{for (int i = 1; i <= 5; i++){push(i);}while (size()){cout << top() << " ";pop();}return 0;
}

2. priority_queue

优先级队列:元数被赋予优先级(权重),当在队尾插入元素时,会根据优先级进行比较调位;删除元素,也会根据优先级进行调位,队头(顶)先删除

(可以认为,优先级队列就是实现的数据结构

2.1 内置类型的的创建

#include<iostream>
#include<queue>//优先级队列的头文件
using namespace std;int main()
{//默认创建一个大根priority_queue<int> heap;//插入,时间复杂度O(log N)for (int i = 1; i <= 5; i++){heap.push(i);}//返回元素个数,时间复杂度O(1)cout << heap.size() << endl;//返回优先级最高元素,时间复杂度O(1)cout << heap.top() << endl;//删除,时间复杂度O(log N)for (int i = 1; i <= 5; i++){heap.pop();}//返回是否为空,时间复杂度O(log N)cout << heap.empty() << endl;return 0;}

2.2 结构体类型

优先级队列的原始创建:

#include<iostream>
#include<queue>//优先级队列的头文件
using namespace std;//priority_queu<数据类型,存储数据的结构,数据的比较方式>
//大根的比较为小于
priority_queue<int, vector<int>, less<int>> heap1;
//小根的比较为大于
priority_queue<int, vector<int>, greater<int>> heap2;//对于内置类型,可以直接传递

对于非内置类型如结构体:

1. 可以在结构体中重载  < 比较运算符

2. 可以传递比较函数

#include<iostream>
#include<queue>//优先级队列的头文件
using namespace std;struct node
{int a, b, c;//定义小根,大于比较,以b为比较基准/*bool operator < (const node& x)const{return b > x.b;}*///定义大根,小于比较,以b为比较基准bool operator < (const node& x)const{return b < x.b;}
};void test()
{priority_queue<node> heap;for (int i = 1; i <= 5; i++){heap.push({i, i, i});}while (heap.size()){auto e = heap.top(); heap.pop();cout << e.b << " ";}cout << endl;
}
int main()
{test();return 0;
}


http://www.ppmy.cn/embedded/169198.html

相关文章

axios几种请求类型的格式

Axios 是一个基于 Promise 的 HTTP 客户端&#xff0c;广泛用于浏览器和 Node.js 中发送 HTTP 请求。它支持多种请求格式&#xff0c;包括 GET、POST、PUT、DELETE 等。也叫RESTful 目录 一、axios几种请求类型的格式 1、get请求 2、post请求 3、put请求 4、delete请求 二…

秒验:重构APP用户体验与运营效率

秒验&#xff1a;重构APP用户体验与运营效率 在移动互联网竞争日益激烈的今天&#xff0c;APP用户对便捷性和安全性的需求持续升级。传统短信验证码的“输入-等待-验证”流程&#xff0c;因延迟、操作繁琐等问题&#xff0c;已成为用户流失的重要漏斗。而基于运营商网关的“一…

拍照自带解说?水印相机,让CAD照片标注“开口说话”!

在施工造价等领域的工作中&#xff0c;现场图片与图纸的结合使用是非常常见的场景。以往&#xff0c;我们可能会花费大量时间去整理和标记图片&#xff0c;以便与图纸准确对应。 现在&#xff0c;借助CAD快速看图-水印相机功能&#xff0c;这些问题都能轻松解决&#xff01; …

SpringBoot集成Flink-CDC,实现对数据库数据的监听

一、什么是 CDC &#xff1f; CDC 是Change Data Capture&#xff08;变更数据获取&#xff09;的简称。 核心思想是&#xff0c;监测并捕获数据库的变动&#xff08;包括数据或数据表的插入、 更新以及删除等&#xff09;&#xff0c;将这些变更按发生的顺序完整记录下来&…

反爬虫策略

反爬虫策略是网站用于防止自动化程序&#xff08;爬虫&#xff09;恶意抓取数据的核心手段&#xff0c;其设计需兼顾有效性、用户体验和合法性。 一、 基础检测与拦截 User-Agent检测&#xff1a;验证请求头中的User-Agent&#xff0c;拦截非常见或已知爬虫标识。IP频率限制&…

TCP基本入门-简单认识一下什么是TCP

部分内容来源&#xff1a;小林Coding TCP的特点 1.面向连接 一定是“一对一”才能连接&#xff0c;不能像 UDP 协议可以一个主机同时向多个主机发送消息&#xff0c;也就是一对多是无法做到的 2.可靠的 无论的网络链路中出现了怎样的链路变化&#xff0c;TCP 都可以保证一个…

MVC架构

MVC架构 为什么要关注架构&#xff1f; 架构 就像房子一样&#xff0c;软件也需要一个结构: 这是我们组织代码的方式&#xff1b; 可维护性 项目永远没有终点&#xff01;我们需要能够在未来轻松地对其进行修改。 可扩展性 我们还需要可以轻松的添加新功能 在构建完美的…

怎么进行mysql的优化?

MySQL 的优化是一个系统性的工作&#xff0c;涉及多个层面&#xff0c;包括查询优化、索引优化、配置优化、架构优化等。以下是一些常见的 MySQL 优化方法&#xff1a; 查询优化 避免全表扫描&#xff1a;确保查询能够使用索引&#xff0c;避免 SELECT *&#xff0c;只选择需要…