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.hqwc.cn/news/696404.html

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

相关文章

(三)小程序样式和组件

视频链接&#xff1a;尚硅谷2024最新版微信小程序 文章目录 小程序的样式和组件介绍样式-尺寸单位 rpx样式-全局样式和局部样式组件-组件案例演示组件案例-轮播图区域绘制组件案例-轮播图图片添加组件案例-绘制公司信息区域组件案例-商品导航区域组件案例-跳转到商品列表组件案…

使用Vue3开发项目,搭建Vue cli3项目步骤

1.打开cmd &#xff0c;输入 vue create neoai遇到这样的问题 则需要升级一下电脑上 Vue Cli版本哈 升级完成之后 再次输入命令&#xff0c;创建vue3项目 vue create neoai安装完成后&#xff0c;输入 npm run serve 就可以运行项目啦~ 页面运行效果

基于微信小程序+JAVA Springboot 实现的【马拉松报名系统】app+后台管理系统 (内附设计LW + PPT+ 源码+ 演示视频 下载)

项目名称 项目名称&#xff1a; 马拉松报名系统微信小程序 项目技术栈 该项目采用了以下核心技术栈&#xff1a; 后端框架/库&#xff1a; Java SSM框架数据库&#xff1a; MySQL前端技术&#xff1a; 微信开发者工具、uni-app其他技术&#xff1a; JSP开发技术 项目展示 …

绝地求生PUBG初版艾伦格回归 初版艾伦格和新版有什么区别

PUBG终于迎来了经典的旧版艾伦格地图的回归&#xff01;我们希望通过本次经典艾伦格的回归为大家带回记忆中那一幕幕熟悉的场景&#xff0c;并让大家好好回味一番当年与好友们共同冒险的峥嵘岁月&#xff01;还怀念从前为了抢到自己最爱的武器而飞奔的日日夜夜吗&#xff1f;那…

InstantStyle —— 文本到图像生成中的风格保持新突破

在人工智能领域&#xff0c;文本到图像生成&#xff08;Text-to-Image Generation&#xff09;技术正迅速发展&#xff0c;其应用范围从娱乐到专业设计不断扩展。然而&#xff0c;风格一致性生成一直是该领域的一个技术难题。最近&#xff0c;InstantX团队提出了一种名为Instan…

MyBatis——模拟MyBatis框架

一、dom4j 解析 XML 文件 在 dom4j 中&#xff0c;DOMReader 和 SAXReader 是两种不同的 XML 解析器。 它们的主要区别在于解析 XML 的方式和所提供的功能&#xff1a; DOMReader&#xff1a; DOMReader 使用 DOM&#xff08;Document Object Model&#xff09;模型来表示整个…

国内使用 CloudFlare 避坑指南

最近明月收到了不少新手使用 CloudFlare 的求助,发现很多首次使用 CloudFlare 的甚至包括已经在使用 CloudFlare 的站长们对 CloudFlare 的使用有很多的误区,再加上国内简中互联网上有关 CloudFlare 的教程良莠不齐,更是加深了新手使用 CloudFlare 入坑的概率,让一些别有用…

基于51单片机的冰箱控制系统设计( proteus仿真+程序+设计报告+原理图+讲解视频)

基于51单片机冰箱控制系统设计( proteus仿真程序设计报告原理图讲解视频&#xff09; 基于51单片机冰箱控制系统设计 1. 主要功能&#xff1a;2. 讲解视频&#xff1a;3. 仿真4. 程序代码5. 设计报告6. 原理图7. 设计资料内容清单&&下载链接资料下载链接&#xff1a; …

内容与图像一对多问题解决

场景复现 分析&#xff1a; 其实这是两给表&#xff0c;一个内容表&#xff0c;一个图片表&#xff0c;一对多的关系。 解决思路: 1. 先上传图片拿到图片的List集合ids&#xff0c;返回值是集合的ids&#xff0c;给到前端 2. 再添加内容表的数据生成了id&#xff0c;遍历查…

GPT搜索引擎原型曝光!

OpenAI发布会前一天&#xff0c;员工集体发疯中……上演大型套娃行为艺术。 A&#xff1a;我为B的兴奋感到兴奋&#xff1b;B&#xff1a;我为C的兴奋感到兴奋……Z&#xff1a;我为这些升级感到兴奋 与此同时还有小动作不断&#xff0c;比如现在GPT-4的文字描述已不再是“最先…

怎么ai拍照搜题?让你的学习之路更平坦!

怎么ai拍照搜题&#xff1f;在数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;的广泛应用已经渗透到我们生活的方方面面&#xff0c;其中AI拍照搜题功能更是受到了广大学子的热烈欢迎。这一功能通过拍照上传题目&#xff0c;利用AI技术快速识别并分析题目内容&#…

Mysql数据类型设计思考

一、Mysql数据类型设计规范 1.1 选择更小的数据类型 一般情况下&#xff0c;在满足存储要求的基础上&#xff0c;尽量选择小的存储类型。例如&#xff1a;存储0~200&#xff0c;tinyint和bigint都可以存储&#xff0c;那么选择tinyint。原因&#xff1a;越小的数据类型运算速…