目录

引言

堆的基本概念与特性

 堆的插入与向上调整

堆的删除与向下调整

优先队列的设计思路

模板参数设计

 比较器的作用 

核心接口实现

push

pop

top

附录(完整代码) 


引言

        优先队列(Priority Queue)是一种特殊的队列数据结构,其中每个元素都有一个优先级。与普通队列不同,优先队列中的元素不是按照先进先出的原则出队,而是按照优先级的高低出队。本文将详细介绍优先队列的实现,包括其底层数据结构——堆的原理,以及完整的C++实现代码。

堆的基本概念与特性

        堆是一种完全二叉树,分为最大堆和最小堆。最大堆中父节点值大于等于子节点,最小堆中父节点值小于等于子节点。这种特性使得堆能高效地维护数据的优先级。

        完全二叉树的数组表示法通过下标关系定位父子节点:

  • 已知子节点下标i:父节点索引:(i - 1) / 2;
  • 已知父节点下标i:左子节点:2*i + 1,右子节点:2*i + 2;

 堆的插入与向上调整

插入操作将新元素置于数组末尾,通过向上调整(adjustUp)维护堆结构:

  1. 比较新节点与父节点的值;
  2. 若违反堆序(最大堆中子节点更大,或最小堆中子节点更小),交换两者;
  3. 重复过程直至根节点或堆序满足。

堆的删除与向下调整

删除堆顶元素时,将末尾元素移至堆顶,通过向下调整(adjustDown)恢复堆结构:

  1. 从根节点开始,比较其与较大(最大堆)或较小(最小堆)子节点的值;
  2. 若违反堆序,交换两者并继续向下检查;
  3. 终止于叶子节点或堆序满足时。

优先队列的设计思路

        优先队列基于堆实现,支持高效获取最高/低优先级元素。关键设计包括:

模板参数设计

  • T:元素类型。
  • Container:默认vector,需支持随机访问和动态扩容。
  • Compare:比较器,默认Less<T>实现最大堆,Greater<T>实现最小堆。

 比较器的作用 

        通过模板参数Compare实现灵活的大小比较策略: 

template <class T>
class Less
{
public:bool operator()(const T& x, const T& y){return x < y;}
};template <class T>
class Greater
{
public:bool operator()(const T& x, const T& y){return x > y;}
};

核心接口实现

push

插入元素并向上调整堆:

public:void push(T data){_con.push_back(data);adjustUp();}
private:void adjustUp(){int child = _con.size() - 1;int parent = (child - 1) / 2;while (parent >= 0){if (com(_con[parent], _con[child])){swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}else break;}}

pop

移除堆顶元素并向下调整堆:

public:T pop(){T data = _con.front();swap(_con[0], _con[_con.size() - 1]);_con.pop_back();adjustDown();return data;}
private:void adjustDown(){int parent = 0;int child = 1;while (child < size()){if (child + 1 < size()){if (com(_con[child], _con[child + 1])){child = child + 1;}}if (com(_con[parent], _con[child])){swap(_con[parent], _con[child]);parent = child;child = parent * 2 + 1;}else break;}}

top

访问堆顶元素(即数组首元素)

T top() { return _con.front(); }

附录(完整代码) 

#include <vector>
#include <iostream>
#include <cassert>using namespace std;template <class T>
class Less
{
public:bool operator()(const T& x, const T& y){return x < y;}
};template <class T>
class Greater
{
public:bool operator()(const T& x, const T& y){return x > y;}
};template <class T, class Container = vector<T>, class Compare = Less<T>>
class priority_queue
{
public:priority_queue() {}priority_queue(const Container &con) {for (auto& item : con){push(item);}}void push(T data){_con.push_back(data);adjustUp();}T pop(){T data = _con.front();swap(_con[0], _con[_con.size() - 1]);_con.pop_back();adjustDown();return data;}T top() { return _con.front(); }size_t size() { return _con.size(); }bool empty() { return _con.empty(); }private:void adjustUp(){int child = _con.size() - 1;int parent = (child - 1) / 2;while (parent >= 0){if (com(_con[parent], _con[child])){swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}else break;}}void adjustDown(){int parent = 0;int child = 1;while (child < size()){if (child + 1 < size()){if (com(_con[child], _con[child + 1])){child = child + 1;}}if (com(_con[parent], _con[child])){swap(_con[parent], _con[child]);parent = child;child = parent * 2 + 1;}else break;}}private:Container _con;Compare com;
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/89239.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/89239.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/89239.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

现代CSS实战:用变量与嵌套重构可维护的前端样式

现代CSS实战&#xff1a;用变量与嵌套重构可维护的前端样式 引言 在传统CSS开发中&#xff0c;我们常常陷入「样式冗余」与「维护噩梦」的循环&#xff1a; 想调整主题色&#xff1f;得全局搜索所有 #3498db 手动替换&#xff0c;稍有不慎就漏改某个角落&#xff1b; 写嵌套…

DHTMLX Suite 9.2 重磅发布:支持历史记录、类Excel交互、剪贴板、拖放增强等多项升级

全球知名的 JavaScript UI 组件库 DHTMLX Suite 迎来 9.2 新版本&#xff01;此次更新虽为次版本号&#xff0c;却实质性提升了 Grid 网格组件的交互能力与用户体验&#xff0c;引入了包括历史记录管理、剪贴板操作、数据选择范围管理、Block 区块选择等多项高级模块&#xff0…

深入理解Java中的Map.Entry接口

文章目录深入理解Java中的Map.Entry接口1. 接口定义2. 核心方法解析2.1 基本方法2.2 Java 8新增的静态方法3. 基本使用示例3.1 遍历Map的条目3.2 修改Map中的值3.3 使用比较器排序4. Java 8/9增强特性4.1 与Stream API结合4.2 Java 9的equals和hashCode默认方法5. 实际应用场景…

AI培训学习2

不要打扰用户的习惯&#xff0c;比如APP右下角的我的&#xff0c;放到第一个就不合适 先抄再超 lifeTime value NPS: 评价 Product market 平衡 ARPU&#xff1a; LT活跃时长 游戏中好友的重要性 不花钱存活率很少 如何花钱&#xff0c;1分钱买东西 联影医疗 figma uizard…

npm 安装时候怎么指定某一个子包的版本 overrides

有时候用 npm install 安装的时候会报错&#xff0c;比如 express 包依赖 "escape-html": "^1.0.2" 版本的包&#xff0c;但是因为 escape-html" 升级到 1.0.3 版本了&#xff0c;但是这个版本有问题&#xff0c;导致express 下载不下来。怎么固定下载…

python学智能算法(十九)|SVM基础概念-超平面

引言 前序学习进程中&#xff0c;对向量相关的基本知识进行了学习&#xff0c;链接为&#xff1a; 向量的值和方向 向量点积 在实际的支持向量机算法使用中&#xff0c;最核心的目标是找出可以实现分类的超平面&#xff0c;超平面就是分割的点、线或者面&#xff0c;不要在这个…

python 基于 httpx 的流式请求

文章目录1. 环境介绍2. 同步客户端2.1. 面向过程2.1.1. 流式输出2.1.2. 非流式输出2.2. 面向对象3. 异步客户端3.1. 面向过程3.2. 面向对象3.3. Attempted to call a sync iterator on an async stream.参考&#xff1a;https://www.jb51.net/article/262636.htm次要参考&#…

Python 数据建模与分析项目实战预备 Day 4 - EDA(探索性数据分析)与可视化

✅ 今日目标 使用 Pandas Matplotlib/Seaborn 对简历数据进行探索性分析分析不同字段与目标变量的相关性通过可视化呈现简历筛选的潜在规律&#x1f9fe; 一、建议分析内容 &#x1f539; 分类字段分析字段图表建议说明degree柱状图&#xff08;分组通过率&#xff09;分析学历…

力扣每日一题--2025.7.17

&#x1f4da; 力扣每日一题–2025.7.17 &#x1f4da; 3202. 找出有效子序列的最大长度 II&#xff08;中等&#xff09; 今天我们要解决的是力扣上的第 3202 题——找出有效子序列的最大长度 II。这道题是昨天 3201 题的扩展&#xff0c;需要我们处理更一般化的情况。 ⚠️…

github不能访问怎么办

访问&#xff1a;“github.com”国内多个地点网站测速结果_网站测速 - 站长工具访问“github.global.ssl.fastly.net”国内多个地点网站测速结果_网站测速 - 站长工具复制红框中的ip 打开“C:\Windows\System32\drivers\etc\hosts”文件输入&#xff1a; 20.205.243.166 githu…

【深度学习新浪潮】AI在finTech领域有哪些值得关注的进展?

近年来,AI在金融科技(FinTech)领域的应用呈现爆发式增长,尤其在大模型技术突破和政策支持的双重驱动下,多个关键领域取得了显著进展。以下是值得关注的核心方向及具体案例: 一、大模型技术重塑金融服务范式 以DeepSeek为代表的国产大模型通过开源和低成本部署(本地化成…

【中等】题解力扣22:括号生成

题目详情 数字 n 代表生成括号的对数&#xff0c;设计一个函数生成所有可能的并且有效的括号组合。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;[“((()))”,“(()())”,“(())()”,“()(())”,“()()()”] 示例 2&#xff1a; 输入&#xff1a;n 1 输出&#…

【JEECG 组件扩展】JSwitch开关组件扩展单个多选框样式

功能说明&#xff1a;基于JeecgBoot开源框架&#xff0c;JSwitch开关组件扩展&#xff0c;支持单个多选样式。效果展示&#xff1a;使用示例&#xff1a;{field: JSwitch,component: JSwitch,label: JSwitch,},{field: JSwitchCheckBox,component: JSwitch,label: JSwitchCheck…

(转)Kubernetes基础介绍

Kubernetes是用于自动部署、扩展和管理容器化应用程序的开源系统。

vue 播放海康m3u8视频流笔记

1、安装hls.jsnpm i hls 2、使用<el-dialogtitle"监控"top"5vh":visible.sync"dialogVisible"width"30%"><video id"video" style"width:100%;height:300px" controls><sourcetype"applicati…

如何清除 npm 缓存

清除 npm 缓存&#xff1a;利弊分析与操作指南 在使用 Node.js 和 npm 进行项目开发时&#xff0c;我们经常会与 npm install 命令打交道。这个过程中&#xff0c;npm 会在本地建立一个缓存机制&#xff0c;用以存储已下载的包&#xff0c;从而显著提升后续安装的速度。然而&am…

Java学习-----消息队列

消息队列是分布式系统中重要的组件之一。使用消息队列主要是为了通过异步处理提高系统性能和削峰、降低系统耦合性。使用消息队列主要有三点好处&#xff1a;&#xff08;1&#xff09;通过异步处理提高系统性能&#xff08;减少响应所需时间&#xff09;&#xff1a;用户提交请…

玩转Docker | 使用Docker部署TeamMapper思维导图应用程序

玩转Docker | 使用Docker部署TeamMapper思维导图应用程序 前言 一、TeamMapper介绍 TeamMapper简介 TeamMapper功能 二、系统要求 环境要求 环境检查 Docker版本检查 检查操作系统版本 三、部署TeamMapper服务 下载TeamMapper镜像 编辑部署文件 创建容器 检查容器状态 检查服务…

深入解析Linux进程创建与fork机制

目录 一、fork函数初识 二、fork函数返回值 思考&#xff1a; 1. fork函数为何给子进程返回0&#xff0c;而给父进程返回子进程的PID&#xff1f; 2. 关于fork函数为何有两个返回值这个问题 三、写时复制机制 写时拷贝&#xff08;Copy-On-Write&#xff09;机制解析 1.…

【软件开发】主流 AI 编码插件

主流 AI 编码插件1. GitHub Copilot 支持平台&#xff1a;VS Code、Neovim、JetBrains 系列、Visual Studio 优点 深度语料库&#xff1a;基于 OpenAI 的大规模模型训练&#xff0c;能够生成高质量、上下文相关的代码补全。多语言支持&#xff1a;对 Python、JavaScript、TypeS…