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~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode343:整数拆分

题目描述 给定一个正整数 n &#xff0c;将其拆分为 k 个 正整数 的和&#xff08; k > 2 &#xff09;&#xff0c;并使这些整数的乘积最大化。 返回 你可以获得的最大乘积 。 代码 动态规划 class Solution { public:int integerBreak(int n) {/*dp[i]&#xff1a;表示对…

CANopen总线_CANOpen开源协议栈

CANopen是自动化中使用的嵌入式系统的通信协议栈和设备配置文件规范。就OSI 模型而言&#xff0c;CANopen 实现了以上各层&#xff0c;包括网络层。 CANopen 标准由一个寻址方案、几个小型通信协议和一个由设备配置文件定义的应用层组成。通信协议支持网络管理、设备监控和节点…

【c++】二叉搜索树(BST)

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好&#xff0c;本篇文章来到二叉搜索树的内容 目录 1.二叉搜索树的介绍2.二叉搜索树的操作与实现insert插入Find查找InOrder中序遍历Erase删除 3.二叉搜索树的应用&#xff08;K…

代理IP可靠吗?哪里可以找到可靠的代理?

需要代理来访问受限制的网站或改善您的在线隐私&#xff1f;别再犹豫了&#xff01;在这篇博文中&#xff0c;我们将探讨您可以使用的选项&#xff0c;并提供有关在哪里获取代理的指导。 首先&#xff0c;让我们了解什么是代理及其工作原理。代理充当您的设备和互联网之间的中介…

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

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

git版本控制器详解(3)本地和远端同步

为什么要使用gitee&#xff1f; gitee是基于git所搭建的网站&#xff0c;会给我们提供一个稳定的服务器保存我们的版本信息。因为github是国外网站&#xff0c;国内访问速度不够稳定&#xff0c;所以我们选择使用gitee。 前边我们讲解了如何在本地进行操作&#xff0c; 接下来进…

Ranger 面试题及答案整理,最新面试题

Ranger 的安全模型是如何设计的&#xff1f; Ranger的安全模型设计主要基于访问控制和安全策略的管理&#xff0c;它通过以下几个关键组件实现&#xff1a; 1、策略管理&#xff1a; Ranger 提供了一个中央管理平台&#xff0c;用于定义、更新和管理安全策略。这些策略根据资…

【小白入门篇6】常识|怎么计算模型需要的资源

01 背景 各个公司相继推出大模型, 有开源和不开源,有些技术爱好者也开始心痒难耐&#xff0c;萌生了私有本地模型,甚至有伙伴构建大模型并进行训练的想法, 大模型不仅比拼技术, 也是比拼爹(资源)的存在, 我个人在实战经历经常问自己,到底需要什么样配置才能跑起来这个模型, 完…

Mysql数据类型设计思考

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

【项目】Boost搜索引擎

项目相关背景 现在市面上已经出现很多搜索引擎&#xff0c;比如&#xff1a;百度、Google、Bing等等&#xff0c;它们都是全网性搜索 而我做得项目就像cplusplus网站中搜索C的相关知识一样&#xff0c;同样做的是站内搜索&#xff0c;它的搜索更垂直。 搜索引擎的宏观原理 ser…

模型 洋葱模型(组织管理方向)

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。层层深入&#xff0c;探索核心。 1 洋葱模型的应用 1.1 洋葱模型用于职业规划 有一个名叫李明的大学生&#xff0c;他最近感到迷茫和压力&#xff0c;因为他即将毕业并面临职业选择。李明决定寻求心…

Java中55种锁,高级面试题,最新面试题

Java中乐观锁在实际应用中如何解决并发问题&#xff1f; 乐观锁通过假设并发冲突发生概率较低来解决并发问题&#xff0c;主要通过数据版本控制实现。在更新数据前&#xff0c;会检查数据版本是否发生变化&#xff0c;只有在数据版本未变时才允许更新&#xff0c;这样可以避免…

uos server 无法通过ssh工具连接

问题现象 uos server 服务器操作系统 在虚拟机中安装好之后&#xff0c;防火墙已经关闭&#xff0c;ssh服务已经启动&#xff0c;但通过finalshell等ssh工具连接报错 &#xff1a;java.net.ConnectException: Connection timed out: connect 经过确认 防火墙已关&#xff0c;s…

计算机毕业设计springboot体育馆场地预约管理系统【附源码】

计算机毕业设计springboot体育馆场地预约管理系统[附源码] &#x1f345; 作者主页 网顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制…

人工智能生成图像的兴起:区分事实与虚构

人工智能生成图像的兴起&#xff1a;区分事实与虚构 概述 在人工智能 (AI) 已融入我们日常生活的时代&#xff0c;人工智能生成图像的快速发展引发了人们对数字内容真实性的担忧。最近&#xff0c;人工智能生成的图像甚至欺骗了最敏锐的眼睛&#xff0c;这引发了人们对批判性…

@游戏行业er!MongoDB广州线下沙龙邀您报名!

随着游戏和应用程序的发展&#xff0c;数据变得越来越重要。在为您的下一个游戏选择数据库时&#xff0c;数据库管理者常常会面对灵活性、可扩展性、可靠性、运营效率等问题或挑战。 MongoDB在游戏开发领域有着广泛的应用&#xff0c;灵活数据模型可以存储和处理各种类型的数据…

OPT系列极速版远距离光数据传输器|光通讯传感器安装与调试方法

OPT系列极速版远距离光数据传输器|光通讯传感器使用红外激光通信&#xff0c;满足全双工 100M 带宽&#xff0c;通讯距离可达 300 米。能够快速&#xff0c;稳地传送数据&#xff0c;支持主流的工业控制总线&#xff08;Profinet&#xff0c;Ethercat 等&#xff09;&#xff1…

媒体宣发:多元宣发方式的方式有哪些

在信息爆炸的今天&#xff0c;媒体宣发被广泛地运用在各个领域&#xff0c;对于产品宣传、企业形象塑造等都起着至关重要的作用。多样化的媒体宣发方式越来越受到企业的重视&#xff0c;那么常见的媒体宣发方式有哪些呢&#xff1f; 首先&#xff0c;新闻发布是最传统也是最直…

SQLStringInFo SQL 数据库操作语句的解析器!!!

SQLStringInFo 开源技术栏 SQLStringInFo是一个专注于sql命令语句解析的sql命令解析库&#xff0c;在库中提供了有关SQL命令语法的解析器&#xff0c;通过该库&#xff0c;可以实现快速准确的SQL语句分析处理。 介绍 SQLStringInFo是一个专注于sql命令语句解析的sql命令解析…

形位公差Overview of GDT

零件公差产生于十九世纪后期&#xff0c;其初衷是为了保证零件的互换性。起初只有尺寸公差。由于 当时的设计部门和制造部门通常都在一起或就在隔壁&#xff0c;因此交流起来非常方便。在当时&#xff0c;给 定的公差一般都很大&#xff0c;因此当时的设备刀具的能力对于保证产…