C++入门-stack和queue(下)

大家好啊,在这先祝天下的母亲节日快乐啦!现在呢,给大家带来C++中priority_queue和容器适配器的相关知识点
在这里插入图片描述

3.1 C++ 中的优先队列(priority_queue)介绍

优先队列(priority_queue)是一种特殊的队列,它的特点是可以按照元素的优先级进行排序,每次取出的元素都是优先级最高(或最低)的元素。在 C++ 中,优先队列是通过标准库中的std::priority_queue实现的。

优先队列的介绍

优先队列是一种数据结构,它与队列类似,但是不同之处在于优先队列中的元素是按照一定的优先级顺序进行排序的。当我们向优先队列中插入元素时,元素会按照一定的规则进行排序,而取出元素时,会先取出优先级最高(或最低)的元素。

在 C++ 中,优先队列是一个适配器容器(adapter container),它基于另一个底层容器(通常是std::vector)实现,并提供了一些特殊的操作,使得元素按照优先级进行管理。

优先队列的使用

下面是一个简单的示例代码,演示了如何使用std::priority_queue创建一个最大堆(默认情况下是最大堆):

#include <iostream>
#include <queue>int main() {std::priority_queue<int> pq;pq.push(30);pq.push(10);pq.push(20);std::cout << "Top element: " << pq.top() << std::endl;pq.pop();std::cout << "Top element after pop: " << pq.top() << std::endl;return 0;
}

注释:

  • std::priority_queue是 C++ 标准库中实现优先队列的类。
  • push 方法用于将元素插入优先队列。
  • top 方法用于获取优先队列中的顶部元素(优先级最高的元素)。
  • pop 方法用于移除优先队列中的顶部元素。

在上面的示例中,我们创建了一个最大堆优先队列,并演示了插入元素、访问顶部元素和移除顶部元素的操作。

优先队列在实际应用中常用于任务调度、贪心算法等场景,可以方便地管理具有优先级的元素。

3.2 C++ 中的队列(queue)在 OJ 中的应用

在我们平时做的OJ题中,队列(queue)是一种常用的数据结构,能够帮助我们解决各种问题,如广度优先搜索(BFS)等。在 C++ 中,我们可以使用标准库中的std::queue来实现队列的功能。

在 OJ 中的使用

下面是一个示例代码,演示了如何在 OJ 中使用队列解决一个简单的问题:

问题描述:
给定一个整数数组,求解数组中所有元素的和。

#include <iostream>
#include <queue>int main() {// 创建一个队列,元素类型为整数std::queue<int> q;// 将数组元素依次入队int arr[] = {1, 2, 3, 4, 5};for (int i = 0; i < 5; i++) {q.push(arr[i]);}// 计算队列中所有元素的和int sum = 0;while (!q.empty()) {sum += q.front(); // 获取队首元素q.pop(); // 弹出队首元素}// 输出结果std::cout << "数组元素的和为:" << sum << std::endl;return 0;
}

注释:

  • std::queue是 C++ 标准库中实现队列的类,用于存储元素并支持先进先出(FIFO)的操作。
  • push 方法用于将元素入队。
  • front 方法用于获取队首元素。
  • pop 方法用于弹出队首元素。
  • empty 方法用于判断队列是否为空。

在上面的示例中,我们创建了一个队列,并将整数数组中的元素依次入队,然后计算队列中所有元素的和。通过队列的先进先出特性,我们可以方便地处理需要按顺序处理的数据。

在实际的算法竞赛中,队列常常与广度优先搜索(BFS)算法结合使用,用于遍历图中的节点或解决其他问题。

3.3 C++ 中的优先队列(priority_queue)的模拟实现

优先队列(priority_queue)是一种特殊的队列,它可以按照一定的优先级顺序存储元素,并且每次取出的元素都是优先级最高的。在 C++ 中,我们可以使用标准库中的std::priority_queue来实现优先队列的功能。下面我们将通过自定义类来模拟实现一个简单的优先队列。

模拟实现

下面是一个示例代码,演示了如何使用一个自定义类来模拟实现优先队列的基本功能:

#include <iostream>
#include <vector>
#include <algorithm>// 自定义比较函数,用于优先级比较
struct Compare {bool operator()(int a, int b) {return a < b; // 定义优先级,这里是升序}
};int main() {// 使用 vector 来模拟优先队列std::vector<int> vec = {3, 1, 4, 1, 5, 9};// 使用自定义的比较函数来定义优先队列std::priority_queue<int, std::vector<int>, Compare> pq(vec.begin(), vec.end());// 输出优先队列中的元素(按照优先级顺序)while (!pq.empty()) {std::cout << pq.top() << " "; // 获取优先级最高的元素pq.pop(); // 弹出优先级最高的元素}return 0;
}

注释:

  • std::priority_queue是 C++ 标准库中实现优先队列的类,它默认使用std::less来定义优先级,也可以自定义比较函数。
  • 在示例代码中,我们自定义了一个比较函数Compare,用于定义优先级的比较规则。
  • 我们使用std::vector来存储元素,并将其作为参数传递给std::priority_queue来初始化优先队列。
  • 通过循环遍历优先队列并输出元素,我们可以看到元素按照优先级顺序被取出。

4.1 C++ 中的适配器(Adapter)

适配器是 C++ STL 中的一种重要概念,它可以将一个容器或者类的接口适配成另一个容器或者类的接口,使得原本不兼容的接口可以互相转换和使用。在 STL 中,常见的适配器包括 stack、queue、priority_queue 等。

什么是适配器

适配器是一种设计模式,用于将一个类的接口转换成另一个类的接口。在 C++ STL 中,适配器通常用于将不同容器的接口进行适配,使得它们可以以统一的方式使用。适配器隐藏了容器的具体实现细节,提供了一致的接口,方便开发者使用不同的容器。

示例代码

下面是一个简单的示例代码,演示了如何使用适配器 stack 来实现一个基本的栈功能:

#include <iostream>
#include <stack>int main() {// 创建一个 stack 容器std::stack<int> mystack;// 向栈中压入元素mystack.push(1);mystack.push(2);mystack.push(3);// 输出栈顶元素std::cout << "栈顶元素:" << mystack.top() << std::endl;// 弹出栈顶元素mystack.pop();// 再次输出栈顶元素std::cout << "弹出后的栈顶元素:" << mystack.top() << std::endl;// 检查栈是否为空if (mystack.empty()) {std::cout << "栈为空" << std::endl;} else {std::cout << "栈不为空" << std::endl;}return 0;
}

注释:

  • 在示例代码中,我们使用std::stack适配器来实现栈的功能。
  • 通过push向栈中压入元素,top获取栈顶元素,pop弹出栈顶元素,empty检查栈是否为空。
  • 使用适配器可以方便地实现栈的功能,而不必关心具体的实现细节。

适配器在 C++ STL 中扮演着重要的角色,它提供了一种灵活的方式来使用不同的容器,使得开发更加高效和便捷。在实际开发中,适配器能够帮助我们快速实现各种数据结构和算法,提高代码的可复用性和可维护性。

4.2 C++ STL 中 stack 和 queue 的底层结构详解

在 C++ STL 中,stack(栈)和queue(队列)是两种常用的数据结构,它们分别基于不同的底层结构实现。本文将详细介绍 STL 中 stack 和 queue 的底层结构,并通过示例代码演示它们的使用。

stack 的底层结构

在 C++ STL 中,stack 是基于 deque(双端队列)实现的。deque 是一种双端队列,支持在两端进行高效地插入和删除操作,因此非常适合用来实现栈这种数据结构。stack 在 deque 的基础上封装了一些接口,提供了栈的常用操作,如 push、pop、top 等。

下面是一个示例代码,演示了如何使用 stack:

#include <iostream>
#include <stack>int main() {std::stack<int> mystack;mystack.push(1);mystack.push(2);mystack.push(3);while (!mystack.empty()) {std::cout << mystack.top() << " ";mystack.pop();}return 0;
}

注释:

  • 在示例代码中,我们使用std::stack适配器来实现栈的功能,底层结构是基于 deque 实现的。
  • 使用push向栈中压入元素,top获取栈顶元素,pop弹出栈顶元素,empty检查栈是否为空。
  • stack 封装了 deque 的接口,提供了栈的功能,使得开发者可以方便地使用栈数据结构。

queue 的底层结构

在 C++ STL 中,queue 是基于 deque 或 list 实现的。如果使用 deque 作为底层容器,queue 的操作复杂度会更低;如果使用 list 作为底层容器,queue 的空间复杂度会更低。queue 提供了队列的常用操作,如 push、pop、front、back 等。

下面是一个示例代码,演示了如何使用 queue:

#include <iostream>
#include <queue>int main() {std::queue<int> myqueue;myqueue.push(1);myqueue.push(2);myqueue.push(3);while (!myqueue.empty()) {std::cout << myqueue.front() << " ";myqueue.pop();}return 0;
}

注释:

  • 在示例代码中,我们使用std::queue适配器来实现队列的功能,底层结构可以是 deque 或 list。
  • 使用push向队列中插入元素,front获取队首元素,pop弹出队首元素,empty检查队列是否为空。
  • queue 封装了 deque 或 list 的接口,提供了队列的功能,使得开发者可以方便地使用队列数据结构。

4.3 deque 的简单介绍

deque(双端队列)是 C++ STL 中的一种容器,它是一种双向开口的序列容器,支持在两端进行高效地插入和删除操作。deque 允许在序列的任意位置进行快速插入和删除操作,比 vector 更加灵活。

下面是一个简单的示例代码,演示了如何使用 deque:

#include <iostream>
#include <deque>int main() {std::deque<int> mydeque;mydeque.push_back(1);mydeque.push_back(2);mydeque.push_front(3);for (int i : mydeque) {std::cout << i << " ";}return 0;
}

注释:

  • 在示例代码中,我们使用std::deque容器来创建一个双端队列。
  • 使用push_back在队尾插入元素,push_front在队首插入元素。
  • deque 支持在两端高效地插入和删除元素,是一种灵活的序列容器。

4.4 为什么选择 deque 作为 stack 和 queue 的底层默认容器

在 C++ STL 中,stack 和 queue 这两种容器适配器的底层默认容器是 deque(双端队列)。为什么选择 deque 作为底层容器呢?让我们来详细探讨一下。

为什么选择 deque

  1. 高效的插入和删除操作:deque 支持在两端进行高效的插入和删除操作,这非常适合用来实现栈(stack)和队列(queue)这样需要频繁在两端操作的数据结构。

  2. 随机访问:deque 支持快速的随机访问,可以通过索引直接访问任意位置的元素,这对于实现优先队列(priority_queue)等需要随机访问的数据结构非常重要。

  3. 动态扩展:deque 的内部实现是由多个连续的缓冲区组成的,当需要扩展容量时,可以在两端添加新的缓冲区,这样可以避免频繁的内存重新分配,提高了性能。

  4. 内存分配效率:deque 在内存分配方面相对灵活,可以避免 vector 的频繁内存搬迁,因此在大部分情况下,deque 的性能表现更好。

演示代码

下面是一个简单的示例代码,演示了如何使用 deque 作为 stack 和 queue 的底层容器:

#include <iostream>
#include <stack>
#include <queue>
#include <deque>int main() {// 使用 deque 作为 stack 的底层容器std::stack<int, std::deque<int>> mystack;mystack.push(1);mystack.push(2);mystack.push(3);while (!mystack.empty()) {std::cout << mystack.top() << " ";mystack.pop();}std::cout << std::endl;// 使用 deque 作为 queue 的底层容器std::queue<int, std::deque<int>> myqueue;myqueue.push(1);myqueue.push(2);myqueue.push(3);while (!myqueue.empty()) {std::cout << myqueue.front() << " ";myqueue.pop();}return 0;
}

注释:

  • 在示例代码中,我们使用 deque 作为 stack 和 queue 的底层容器,展示了它们的基本用法。
  • deque 的灵活性和高效性使其成为 stack 和 queue 的理想底层容器选择。

4.5 STL 标准库中对于 stack 和 queue 的模拟实现

在 C++ STL 中,stack 和 queue 是两种常用的容器适配器,它们分别基于 deque(双端队列)实现。让我们来看看如何使用 STL 标准库中的 stack 和 queue,并进行模拟实现。

stack 的模拟实现

#include <iostream>
#include <stack>int main() {// 创建一个 stack 容器std::stack<int> mystack;// 向 stack 中压入元素mystack.push(1);mystack.push(2);mystack.push(3);// 访问栈顶元素std::cout << "栈顶元素:" << mystack.top() << std::endl;// 弹出栈顶元素mystack.pop();// 打印栈中剩余元素std::cout << "剩余元素:";while (!mystack.empty()) {std::cout << mystack.top() << " ";mystack.pop();}return 0;
}

注释:

  • 在示例代码中,我们使用 STL 的 stack 容器模拟了栈的基本操作:压入元素、访问栈顶元素、弹出栈顶元素等。

queue 的模拟实现

#include <iostream>
#include <queue>int main() {// 创建一个 queue 容器std::queue<int> myqueue;// 向 queue 中插入元素myqueue.push(1);myqueue.push(2);myqueue.push(3);// 访问队首元素std::cout << "队首元素:" << myqueue.front() << std::endl;// 弹出队首元素myqueue.pop();// 打印队列中剩余元素std::cout << "剩余元素:";while (!myqueue.empty()) {std::cout << myqueue.front() << " ";myqueue.pop();}return 0;
}

注释:

  • 在示例代码中,我们使用 STL 的 queue 容器模拟了队列的基本操作:插入元素、访问队首元素、弹出队首元素等。

好了,感谢大家看到这,如果觉得本篇文章对你有帮助的话,还请点个赞支持一下,有什么问题也可以评论区留言,那么我们下次再见了,Peace~

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

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

相关文章

洛谷 P6218 [USACO06NOV] Round Numbers S 题解 数位dp

[USACO06NOV] Round Numbers S 题目描述 如果一个正整数的二进制表示中&#xff0c; 0 0 0 的数目不小于 1 1 1 的数目&#xff0c;那么它就被称为「圆数」。 例如&#xff0c; 9 9 9 的二进制表示为 1001 1001 1001&#xff0c;其中有 2 2 2 个 0 0 0 与 2 2 2 个 1 …

Linux部署Heartbeat

环境信息&#xff1a; 10.1.13.75 master 10.1.13.140 slave 10.1.13.247 VIP 一&#xff0c;基础环境处理 1&#xff0c;修改主机名 master节点 hostnamectl set-hostname master slave节点 hostnamectl set-hostname slave 2&#xff0c;修改/etc/hosts vi /etc/hos…

transformer与beter

transformer与beter 解码和编码器含义tokizer标记器和one-hot独热编码编码解码--语义较好的维度空间矩阵相乘--空间变换编码理解如何构造降维的嵌入矩阵--实现到达潜空间上面是基础&#xff0c;下面是transformer正文自注意力机制注意力分数--上下文修正系数为什么需要KQ两个矩…

设计模式-07 设计模式-观察者模式(Observer Pattern)

设计模式-07 设计模式-观察者模式&#xff08;Observer Pattern&#xff09; 1.定义 观察者模式是一种软件设计模式&#xff0c;它定义了一种一对多的依赖关系&#xff0c;其中一个对象&#xff08;称为“主题”&#xff09;维护了一个依赖对象的列表&#xff08;称为“观察者”…

ssm125四六级报名与成绩查询系统+jsp

四六级报名与成绩查询系统的设计与实现 摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对四六级报名信息管理混乱&am…

达梦数据插入操作的深坑

提示错误&#xff1a;Only if specified in the column list and SET IDENTITY_INSERT is ON, then identity column could be assigned value 插入的语句采用缺省的方式实现&#xff0c;执行插入操作失败&#xff1b; 原因分析&#xff1a; 1.自增长的SQL表里面插入指定ID的…

DIFT:Emergent Correspondence from Image Diffusion # 论文阅读

URL https://arxiv.org/pdf/2306.03881 主页&#xff1a;https://diffusionfeatures.github.io/ 代码&#xff1a;https://github.com/Tsingularity/dift TD;DR 23 年 6月 cornell 大学的文章&#xff0c;任务是做图片的特征匹配&#xff08;关联&#xff09;&#xff0c;特…

【kali工具使用】Tcpdump 抓包查看三次握手过程

Tcpdump 抓包查看三次握手过程 tcpdump 常用参数&#xff1a; -c 指定要抓取的数据包数量 -n 对 IP 地址以数字方式显式&#xff0c;否则显式为主机名 port 指定端口 -I 指定 tcpdump 需要监听的接口。默认会抓取第一个网络接口 tcp 1ClientSYN1seqx 2Server SYN1 seq…

树莓派|超声波传感器

VCC&#xff1a;超声波模块电源脚&#xff0c;接5V电源即可 Trig&#xff1a;超声波发送脚&#xff0c;高电平时发送出40KHZ出超声波 Echo&#xff1a;超声波接收检测脚&#xff0c;当接收到返回的超声波时&#xff0c;输出高电平 GND&#xff1a;超声波模块GND 测距原理&…

2025考研 | 北京师范大学计算机考研考情分析

北京师范大学&#xff08;Beijing Normal University&#xff09;简称“北师大”&#xff0c;由中华人民共和国教育部直属&#xff0c;中央直管副部级建制&#xff0c;位列“211工程”、“985工程”&#xff0c;入选国家“双一流”、“珠峰计划”、“2011计划”、“111计划”、…

--每周分享--

一、三数之和&#xff1a;15. 三数之和 - 力扣&#xff08;LeetCode&#xff09; public class Solution {public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> result new ArrayList<>();//判断极限条件&#xff1a;长度不…

NCL绘制WRF domain区域并添加气象站点

读取文件 根据官网例子Using gsn_csm_contour_map to plot WRF-ARW data绘制&#xff1a; ; It shows how to use gsn_csm_xxxx scripts to do the plotting. ; ; You can use the map projection settings on the WRF file, or you ; can use your own map projection. See …

路由器、交换机和网卡

大家使用VMware安装镜像之后&#xff0c;是不是都会考虑虚拟机的镜像系统怎么连上网的&#xff0c;它的连接方式是什么&#xff0c;它ip是什么&#xff1f; 路由器、交换机和网卡 1.路由器 一般有几个功能&#xff0c;第一个是网关、第二个是扩展有线网络端口、第三个是WiFi功…

ncs sdk nrf5340 运行DFU

nrf5340 运行DFU 1. dfu介绍 Nordic 的 DFU&#xff08;Device Firmware Update&#xff09;是一种用于更新设备固件的技术和协议。Nordic Semiconductor 是一家专门设计和制造无线芯片的公司&#xff0c;他们的产品主要用于物联网&#xff08;IoT&#xff09;和无线连接应用…

【数据分析面试】42.用户流失预测模型搭建(资料数据分享)

题目 保持高的客户留存率可以稳定和提到企业的收入。因此&#xff0c;预测和防止客户流失是在业务中常见的一项数据分析任务。这次分享的数据集包括了电信行业、银行、人力资源和电商行业&#xff0c;涵盖了不同业务背景下的流失预测数据。 后台回复暗号&#xff08;在本文末…

整理好了!2024年最常见 100 道 Java基础面试题(四十三)

上一篇地址&#xff1a;整理好了&#xff01;2024年最常见 100 道 Java基础面试题&#xff08;四十二&#xff09;-CSDN博客 八十五、Java 常用的元注解有哪些&#xff1f; 在Java中&#xff0c;元注解&#xff08;Meta-Annotation&#xff09;是指那些用于其他注解上的注解&…

React Native 之 开发环境搭建(一)

1. 安装Node.js&#xff1a; Node.js是React Native开发的基础&#xff0c;因此首先需要安装Node.js。强烈建议始终选择 Node 当前的 LTS &#xff08;长期维护&#xff09;版本&#xff0c;一般是偶数版本&#xff0c;不要选择偏实验性质的奇数版本。 如果你希望更方便地管理…

k8sCRD

k8s&&CRD 概念创建一个简单的自定义资源Operator 概念 CRD: CustomResourceDefinition&#xff0c;CustomResourceDefinition represents a resource that should be exposed on the API server. Its name MUST be in the format <.spec.name>.<.spec.group&…

基于SpringBoot+微信小程序的订餐(点餐)配送系统设计与实现+毕业论文(12000字)

系统介绍 本微信小程序在线订餐系统管理员功能可以修改个人中心&#xff0c;用户管理&#xff0c;菜品分类管理&#xff0c;菜品信息管理&#xff0c;订单信息管理&#xff0c;取消订单管理&#xff0c;订单配送管理&#xff0c;菜品评价管理以及系统管理。微信小程序用户可以…

实训一:设计系统主页作业

1.题目 设计系统主页。 2.目的 (1)熟悉Web前端项目开发环境。 (2)掌握如何建立Web前端项目&#xff0c;学会规划项目结构。 (3)掌握动态生成页面内容的方法。 (4)理解如何使用Flash显示图片新闻。 (5)会在应用系统中编写播放动态新闻的程序。 3.内容 建立项目结构&#xff0c;并…