【C++篇】排队的艺术:用生活场景讲解优先级队列的实现

文章目录

须知

💬 欢迎讨论:如果你在学习过程中有任何问题或想法,欢迎在评论区留言,我们一起交流学习。你的支持是我继续创作的动力!

👍 点赞、收藏与分享:觉得这篇文章对你有帮助吗?别忘了点赞、收藏并分享给更多的小伙伴哦!你们的支持是我不断进步的动力!
🚀 分享给更多人:如果你觉得这篇文章对你有帮助,欢迎分享给更多对C++感兴趣的朋友,让我们一起进步!

深入理解与实现:C++优先级队列的模拟实现

1. 引言

在算法和数据结构中,优先级队列是一种极其重要的工具,用于按优先级而非插入顺序处理数据。在C++中,std::priority_queue提供了强大的内置支持,但了解其原理和实现有助于我们更灵活地应用这一数据结构。本文将带你从基础概念出发,逐步实现一个C++版本的优先级队列,并解析其核心原理。

2. 什么是优先级队列?

优先级队列是特殊的队列数据结构,其中每个元素都带有一个优先级,队列的处理顺序依据优先级而定,而不是入队顺序。常见特性包括:

  • 优先级定义:通常用数值表示,数值越大或越小(取决于实现)表示优先级越高。
  • 操作支持:支持插入、删除优先级最高元素。
2.1 现实生活的比喻

在机场登机时,头等舱乘客拥有更高的优先级,会优先登机;在银行排队时,VIP客户的业务会优先处理。优先级队列以数据结构的方式抽象和实现了这些规则。


3. 优先级队列的实现方式

优先级队列的底层通常基于堆结构(Heap)。堆是一种二叉树,分为最大堆和最小堆:

  • 最大堆:根节点是最大值,每个子节点的值都小于或等于父节点。
  • 最小堆:根节点是最小值,每个子节点的值都大于或等于父节点。
3.1 常见实现方法
  • 基于数组或链表:通过手动排序实现,但效率低下。
  • 基于二叉堆:常见且高效,插入和删除的时间复杂度为O(log n)。
  • C++ STL中的实现std::priority_queue利用堆的机制实现优先级队列。

4. 用C++实现优先级队列

接下来,我们将通过代码逐步构建一个优先级队列。

4.1 手动实现优先级队列(基于最大堆)
#include <iostream>
#include <vector>
#include <stdexcept>class PriorityQueue {
private:std::vector<int> heap;void siftUp(int index) {int parent = (index - 1) / 2;if (index > 0 && heap[index] > heap[parent]) {std::swap(heap[index], heap[parent]);siftUp(parent);}}void siftDown(int index) {int left = 2 * index + 1;int right = 2 * index + 2;int largest = index;if (left < heap.size() && heap[left] > heap[largest])largest = left;if (right < heap.size() && heap[right] > heap[largest])largest = right;if (largest != index) {std::swap(heap[index], heap[largest]);siftDown(largest);}}public:void push(int value) {heap.push_back(value);siftUp(heap.size() - 1);}int pop() {if (heap.empty()) {throw std::runtime_error("Priority queue is empty");}int top = heap[0];heap[0] = heap.back();heap.pop_back();if (!heap.empty()) {siftDown(0);}return top;}bool empty() const {return heap.empty();}int top() const {if (heap.empty()) {throw std::runtime_error("Priority queue is empty");}return heap[0];}
};int main() {PriorityQueue pq;pq.push(10);pq.push(20);pq.push(5);std::cout << "Top element: " << pq.top() << std::endl; // 输出 20std::cout << "Popped element: " << pq.pop() << std::endl; // 输出 20std::cout << "Popped element: " << pq.pop() << std::endl; // 输出 10return 0;
}
4.2 使用C++标准库实现优先级队列

C++ STL 提供了内置的优先级队列std::priority_queue,使用起来非常方便。

#include <iostream>
#include <queue>
#include <vector>int main() {// 默认是最大堆std::priority_queue<int> pq;// 插入元素pq.push(10);pq.push(20);pq.push(5);// 查看和删除堆顶元素std::cout << "Top element: " << pq.top() << std::endl; // 输出 20pq.pop();std::cout << "Top element after pop: " << pq.top() << std::endl; // 输出 10// 最小堆的实现std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap;minHeap.push(10);minHeap.push(20);minHeap.push(5);std::cout << "Top element of minHeap: " << minHeap.top() << std::endl; // 输出 5return 0;
}
5. 优先级队列的应用场景

优先级队列在许多场景中有着广泛的应用:

  1. 任务调度:操作系统为任务分配资源时,根据任务的优先级进行处理。
  2. 最短路径算法:如Dijkstra和A*算法,利用优先级队列动态选择路径。
  3. 数据流处理:实时系统中,优先级队列保证关键数据优先处理。

6. 总结

通过本文的介绍,我们从理论到代码,详细解析了优先级队列的实现与应用。手动实现的优先级队列让我们理解了堆的原理,而C++ STL的std::priority_queue提供了高度优化的工具,便于快速开发。掌握优先级队列不仅能提高算法效率,也能帮助我们更灵活地解决实际问题。

7. 延伸阅读
  • C++ STL 中的堆算法:std::make_heapstd::push_heapstd::pop_heap
  • 二叉堆与平衡树的比较
  • 优先级队列的内存优化技术

通过这篇博客,读者将能够深入理解优先级队列的设计思路和实现方法,并学会在实际开发中灵活运用C++的标准工具,提升程序效率和代码质量。

路虽远,行则将至;事虽难,做则必成

下篇文章再会!!! 

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

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

相关文章

【unity】WebSocket 与 EventSource 的区别

WebSocket 也是一种很好的选择&#xff0c;尤其是在需要进行 双向实时通信&#xff08;例如聊天应用、实时数据流等&#xff09;时。与 EventSource 不同&#xff0c;WebSocket 允许客户端和服务器之间建立一个持久的、全双工的通信通道。两者的区别和适用场景如下&#xff1a;…

Oracle 数据库 IDENTITY 列

IDENTITY列是Oracle数据库12c推出的新特性。之所以叫IDENTITY列&#xff0c;是由于其支持ANSI SQL 关键字 IDENTITY&#xff0c;其内部实现还是使用SEQUENCE。 不过推出这个新语法也是应该的&#xff0c;毕竟MyQL已经有 AUTO_INCREMENT列&#xff0c;而SQL Server也已经有IDENT…

前端学习笔记之文件下载(1.0)

因为要用到这样一个场景&#xff0c;需要下载系统的使用教程&#xff0c;所以在前端项目中就提供了一个能够下载系统教程的一个按钮&#xff0c;供使用者进行下载。 所以就试着写一下这个功能&#xff0c;以一个demo的形式进行演示&#xff0c;在学习的过程中也发现了中文路径…

【阅读记录-章节4】Build a Large Language Model (From Scratch)

文章目录 4. Implementing a GPT model from scratch to generate text4.1 Coding an LLM architecture4.1.1 配置小型 GPT-2 模型4.1.2 DummyGPTModel代码示例4.1.3 准备输入数据并初始化 GPT 模型4.1.4 初始化并运行 GPT 模型 4.2 Normalizing activations with layer normal…

浅谈——深度学习和马尔可夫决策过程

深度学习是一种机器学习方法&#xff0c;它通过模拟大脑的神经网络来进行数据分析和预测。它由多层“神经元”组成&#xff0c;每一层从数据中提取出不同的特征。多层次的结构使得深度学习模型可以捕捉到数据中的复杂关系&#xff0c;特别适合处理图片、语音等复杂数据。 马尔可…

Python PDF转JPG图片小工具

Python PDF转JPG图片小工具 1.简介 将单个pdf装换成jpg格式图片 Tip: 1、软件窗口默认最前端&#xff0c;不支持调整窗口大小&#xff1b; 2、可通过按钮选择PDF文件&#xff0c;也可以直接拖拽文件到窗口&#xff1b; 3、转换质量有5个档位&#xff0c;&#xff08;0.25&a…

「qt交叉编译arm64」支持xcb、X11

完整的交叉编译好支持xcb的qt库&#xff08;qt5.15.2、arm64、xcb、no-opengl&#xff09; 已安装xcb、X11库的交叉编译器&#xff08;x86_64-aarch64-linux-gnu&#xff09; 文章目录 1. 修改qmake.conf&#xff0c;指定交叉编译器2. 配置编译选项&#xff0c;执行configureL…

使用SOAtest进行功能回归测试

持续集成是将所有开发人员的工作副本合并到共享的主线上。这个过程使软件开发对开发人员来说更容易访问、更快、风险更小。 阅读这篇文章&#xff0c;让我们了解如何配置Parasoft SOAtest作为持续集成过程的一部分&#xff0c;来执行功能测试和回归测试。我们将介绍如何使用主…

ais_server 学习笔记

ais_server 学习笔记 一前序二、ais init1、时序图如下2. 初始化一共分为以下几个重要步骤&#xff1a;2.1.1、在ais_server中启动main函数&#xff0c;然后创建AisEngine&#xff0c;接着初始化AisEngine2.1.2、解析/var/camera_config.xml 文件&#xff0c;获取相关配置参数。…

L1G3000 任务-浦语提示词工程

基础任务 (完成此任务即完成闯关) 背景问题&#xff1a;近期相关研究指出&#xff0c;在处理特定文本分析任务时&#xff0c;语言模型的表现有时会遇到挑战&#xff0c;例如在分析单词内部的具体字母数量时可能会出现错误。任务要求&#xff1a;利用对提示词的精确设计&#xf…

Unity之一键创建自定义Package包

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity之一键创建自定义Package包 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取&#xff01; …

Redis开发04:Redis的INFO信息解析

命令解释redis_versionRedis 的版本号&#xff0c;这里是 3.2.100。redis_git_sha1Redis 使用的 Git SHA1 校验值&#xff0c;表示当前代码的版本。redis_git_dirty如果 Redis 当前运行的代码是脏版本&#xff08;未提交的修改&#xff09;&#xff0c;该值为 1&#xff0c;否则…

python的Flask框架使用

python的Flask框架使用 python环境搭建conda安装python自带的虚拟环境&#xff1a;venv python环境搭建 官网地址 点击downloads 选择你需要的版本&#xff0c;我这里使用的3.12.6 选择Windows installer (64-bit) 选择自定义安装&#xff0c;勾选以管理员权限安装&#xff0…

网络原理(一)—— http

什么是 http http 是一个应用层协议&#xff0c;全称为“超文本传输协议”。 http 自 1991 年诞生&#xff0c;目前已经发展为最主流使用的一种应用层协议。 HTTP 往往基于传输层的 TCP 协议实现的&#xff0c;例如 http1.0&#xff0c;http1.0&#xff0c;http2.0 http3 是…

CTF之密码学(Polybius密码)

棋盘密码&#xff0c;也称为Polybius密码或方格密码&#xff0c;是一种基于替换的加密方法。以下是对棋盘密码的详细解析&#xff1a; 一、加密原理 棋盘密码使用一个5x5的方格棋盘&#xff0c;其中填充了26个英文字母&#xff08;通常i和j被视为同一个字母并放在同一个格子中…

二刷代码随想录第16天

513. 找树左下角的值 找到深度最大的点&#xff0c;遍历方式左边节点在右边节点前面&#xff0c;找到就返回&#xff0c;一定就是最左下角的值了 class Solution { public:int max_depth -1;int result 0;int findBottomLeftValue(TreeNode* root) {traversal(root, 0);ret…

Dockerfile docker-compose

1、Dockerfile # 使用官方的Python作为基础镜像 FROM python:3.9 # 设置工作目录 WORKDIR /app # 复制当前目录下的所有文件到容器的工作目录中 COPY . /app # 安装所需的Python库 #RUN pip install --no-cache-dir -r requirements.txt # 复制 requirements.txt 并安装依赖…

103.【C语言】数据结构之建堆的时间复杂度分析

1.向下调整的时间复杂度 推导 设树高为h 发现如下规律 按最坏的情况考虑(即调整次数最多) 第1层,有个节点,最多向上调整h-1次 第2层,有个节点,最多向上调整h-2次 第3层,有个节点,最多向上调整h-3次 第4层,有个节点,最多向上调整h-4次 ... 第h-1层,有个节点,最多向上调整1次 第…

用Python爬虫“偷窥”1688商品详情:一场数据的奇妙冒险

引言&#xff1a;数据的宝藏 在这个信息爆炸的时代&#xff0c;数据就像是一座座等待挖掘的宝藏。而对于我们这些电商界的探险家来说&#xff0c;1688上的商品详情就是那些闪闪发光的金子。今天&#xff0c;我们将化身为数据的海盗&#xff0c;用Python这把锋利的剑&#xff0…

Python基础学习-12匿名函数lambda和map、filter

目录 1、匿名函数&#xff1a; lambda 2、Lambda的参数类型 3、map、 filter 4、本节总结 1、匿名函数&#xff1a; lambda 1&#xff09;语法&#xff1a; lambda arg1, arg2, …, argN : expression using arg 2&#xff09; lambda是一个表达式&#xff0c;而不是一个语…