STL——栈和队列和优先队列

news2024/9/22 15:35:31

栈和队列和优先队列

  • 概述
  • std::堆栈
    • 核心函数和操作
    • 成员函数
    • 示例
    • 注意事项
  • std::队列
    • 核心函数和操作
    • 成员函数
    • 示例
    • 注意事项
  • std::优先队列
    • 底层实现原理
    • 效率分析
    • deque双端队列
      • 原理
      • 块结构:
      • 指针管理:
      • 元素访问:
      • 示例代码

概述

学到这里对于容器的基础内容都是大概掌握了的,所以直接讲重点

栈(Stack)

栈是一种后进先出(LIFO, Last In First Out)的数据结构,类比为一个容器,你只能从容器的顶部(栈顶)添加或移除元素,不能在中间或底部进行操作。栈的基本操作包括:

  • 压入(Push):将元素放入栈顶。
  • 弹出(Pop):从栈顶移除元素。
  • 查看栈顶元素(Top):查看但不移除栈顶元素。
  • 判空(Empty):判断栈是否为空。
  • 大小(Size):获取栈中元素的个数。

栈常用于需要“后进先出”操作的场景,比如函数调用的执行过程(存储局部变量和调用信息)、表达式求值(处理运算符优先级)、浏览器的返回按钮(记录访问历史)等。

队列(Queue)

队列是一种先进先出(FIFO, First In First Out)的数据结构,类比为排队,你只能从队列的一端(队尾)添加元素,从另一端(队首)移除元素。队列的基本操作包括:

  • 入队(Enqueue):将元素添加到队列的末尾。
  • 出队(Dequeue):从队列的头部移除元素。
  • 查看队首元素(Front):查看但不移除队首元素。
  • 查看队尾元素(Back):查看但不移除队尾元素。
  • 判空(Empty):判断队列是否为空。
  • 大小(Size):获取队列中元素的个数。

队列常用于需要“先进先出”操作的场景,比如任务调度(先到先服务)、缓冲管理(网络数据包传输)、打印队列(打印机任务管理)等。

优先队列(Priority Queue)

优先队列是一种根据元素的优先级来确定出队顺序的队列,而不是严格的先进先出。具体来说,每次出队操作都会返回具有最高(或最低)优先级的元素。优先队列的特点是:

元素之间有优先级顺序,高优先级的元素先出队。

通常使用堆(Heap)这种数据结构来实现,因为堆能够高效地支持插入和删除操作,并保持元素的部分有序性。

基本操作包括插入元素、获取顶部元素(具有最高优先级的元素)、删除顶部元素等。

优先队列常用于需要动态维护一组数据中的优先级顺序的场景,比如任务调度(优先级高的任务优先执行)、事件模拟(按照发生时间的优先级处理事件)等。

在这里插入图片描述

std::堆栈

template <class T, class Container = deque > class stack;

后进先出堆栈

堆栈是一种容器适配器,专门设计用于在后进先出环境(后进先出)下运行,其中元素仅从容器的一端插入和提取。

堆栈S 作为容器适配器实现,这些适配器是使用特定容器类的封装对象作为其底层容器的类,提供一组特定的成员函数来访问其元素。元素从特定容器的“背面”推出/弹出,该容器称为堆栈的顶部。

底层容器可以是任何标准容器类模板,也可以是其他一些专门设计的容器类。容器应支持以下操作:

empty
size
back
push_back
pop_back

标准容器类,并满足这些要求。默认情况下,如果未为特定类实例化指定容器类,则使用标准容器。

核心函数和操作

构造函数和析构函数

  • stack:创建一个空栈,其中 T 是存储的数据类型。
  • stack(const stack& other):复制构造函数,用于复制另一个栈的内容。

成员函数

  • push(const T& value):将元素压入栈顶。
  • pop():从栈顶移除元素,不返回任何值。
  • top():返回栈顶元素的引用,但不将其从栈中移除。
  • empty():检查栈是否为空,返回 true 或 false。
  • size():返回栈中元素的数量。

示例

#include <iostream>
#include <stack>

int main() {
    std::stack<int> s;

    // Pushing elements onto the stack
    s.push(10);
    s.push(20);
    s.push(30);

    // Checking if stack is empty
    if (!s.empty()) {
        std::cout << "Stack size: " << s.size() << std::endl;

        // Accessing top element
        std::cout << "Top element: " << s.top() << std::endl;

        // Popping elements
        s.pop();
        std::cout << "Popped top element." << std::endl;

        // Accessing top element after popping
        std::cout << "Top element now: " << s.top() << std::endl;
    }

    return 0;
}

注意事项

访问栈顶元素:使用 top() 函数之前,需要确保栈非空,否则会导致未定义行为。

移除栈顶元素:使用 pop() 函数会移除栈顶元素,但不返回该元素的值。

复制栈:使用复制构造函数和赋值操作符时,会复制整个栈的内容,包括元素顺序。

空栈访问:尝试在空栈上调用 top() 或 pop() 会导致运行时错误(未定义行为),因此在使用这些操作前应当检查栈是否为空。

std::队列

template <class T, class Container = deque > class queue;

FIFO队列

队列S 是一种容器适配器,专门设计用于在 FIFO 上下文(先进先出)中运行,其中元素插入容器的一端并从另一端提取。

队列 S 作为容器适配器实现,这些适配器是使用特定容器类的封装对象作为其底层容器的类,提供一组特定的成员函数来访问其元素。元素被推入特定容器的“后部”,并从其“前部”弹出。

底层容器可以是标准容器类模板之一,也可以是其他一些专门设计的容器类。此基础容器应至少支持以下操作:
empty
size
front
back
push_back
pop_front

标准容器类别,并满足这些要求。默认情况下,如果未为特定类实例化指定容器类,则使用标准容器。

核心函数和操作

构造函数和析构函数

  • queue:创建一个空队列,其中 T 是存储的数据类型。
  • queue(const queue& other):复制构造函数,用于复制另一个队列的内容。

成员函数

  • push(const T& value):将元素插入队列的末尾。
  • pop():从队列的开头移除元素,不返回任何值。
  • front():返回队列的第一个元素的引用,但不将其从队列中移除。
  • back():返回队列的最后一个元素的引用,但不将其从队列中移除。
  • empty():检查队列是否为空,返回 true 或 false。
  • size():返回队列中元素的数量。

示例

#include <iostream>
#include <queue>

int main() {
    std::queue<int> q;

    // Pushing elements into the queue
    q.push(10);
    q.push(20);
    q.push(30);

    // Checking if queue is empty
    if (!q.empty()) {
        std::cout << "Queue size: " << q.size() << std::endl;

        // Accessing front and back elements
        std::cout << "Front element: " << q.front() << std::endl;
        std::cout << "Back element: " << q.back() << std::endl;

        // Popping elements
        q.pop();
        std::cout << "Popped front element." << std::endl;

        // Accessing front element after popping
        std::cout << "Front element now: " << q.front() << std::endl;
    }

    return 0;
}

注意事项

访问队列元素:使用 front() 和 back() 函数之前,需要确保队列非空,否则会导致未定义行为。

移除队列元素:使用 pop() 函数会移除队列的第一个元素,但不返回该元素的值。

复制队列:使用复制构造函数和赋值操作符时,会复制整个队列的内容,包括元素顺序。

空队列访问:尝试在空队列上调用 front()、back() 或 pop() 会导致运行时错误(未定义行为),因此在使用这些操作前应当检查队列是否为空。

std::优先队列

底层实现原理

在实现优先队列时,通常使用以下两种主要数据结构:

基于堆(Heap)的实现

堆是一种特殊的二叉树,通常实现为数组。

最大堆(Max Heap):父节点的值总是大于或等于任何一个子节点的值。

最小堆(Min Heap):父节点的值总是小于或等于任何一个子节点的值。

在最大堆中,根节点是优先级最高的元素;在最小堆中,根节点是优先级最低的元素。

平衡二叉搜索树的实现

使用平衡二叉搜索树(如红黑树)来维护有序序列,以支持快速的插入、删除和查找操作。

这种实现保证了元素能够按照优先级有序地存储和访问。

效率分析

插入操作

基于堆的优先队列中,插入操作的时间复杂度为 O(log n),其中 n 是当前队列中元素的数量。这是因为插入新元素后,需要调整堆以恢复堆的性质。
平衡二叉搜索树实现的优先队列中,插入操作的时间复杂度为 O(log n),其中 n 是当前队列中元素的数量。这是因为需要保持树的平衡特性。

删除操作

删除操作是指移除优先队列中优先级最高的元素。在基于堆的实现中,删除操作的时间复杂度为 O(log n),因为移除根节点后,需要进行堆的重排。
平衡二叉搜索树实现的优先队列中,删除操作的时间复杂度为 O(log n),因为需要保持树的平衡。

获取最高优先级元素

获取优先队列中优先级最高的元素(即队头元素)的时间复杂度为 O(1)。这是因为在堆中,根节点始终是最大或最小值;在平衡二叉搜索树中,最小或最大元素也可以通过一些常数时间的操作得到。

deque双端队列

deque(双端队列)是C++标准模板库(STL)中的一种容器,它结合了向量(vector)和链表(list)的优点,支持在两端高效地进行元素的插入和删除操作。下面是关于 deque 容器的原理和效率的详细解释:

原理

deque 的名称来源于 “double-ended queue”,即双端队列。它通过一系列的块(chunks)来存储元素,每个块内部通常是一个固定大小的数组,这个数组可以容纳多个元素。deque 的关键设计包括:

块结构:

deque 内部通常由多个块组成,每个块是一个固定大小的数组(或者链表节点)。
每个块存储元素,并且每个块具有前驱和后继块的指针,形成了一个双向链表结构。

指针管理:

deque 维护了指向第一个块和最后一个块的指针,使得在队列的头部和尾部进行快速插入和删除操作成为可能。

对于头部和尾部的插入和删除操作,通过调整指针和在必要时创建或销毁块来维护块的结构。

元素访问:

deque 允许使用迭代器访问元素,迭代器支持双向遍历,并且支持随机访问(通过双向迭代器和块索引的组合实现)。
内存分配:

deque 内部使用动态内存分配来管理块的创建和销毁。这种方式避免了频繁的内存重分配,提高了插入和删除操作的效率。
效率
deque 提供了以下操作的平均时间复杂度:

头部插入和删除(push_front, pop_front):O(1)
尾部插入和删除(push_back, pop_back):O(1)
随机访问(通过迭代器或下标访问):O(1)
相比于 vector 和 list,deque 的主要优势在于

头部操作的高效性:与 vector 相比,deque 的头部插入和删除操作更为高效,因为 vector 需要移动大量元素。
尾部操作的高效性:与 list 相比,deque 在尾部插入和删除操作上的效率更高,因为 list 的每个元素都需要一个额外的指针。

在这里插入图片描述

示例代码

#include <deque>
#include <iostream>

int main() {
    std::deque<int> dq;

    dq.push_back(1);  // 尾部插入
    dq.push_front(2); // 头部插入

    std::cout << dq.front() << " " << dq.back() << std::endl; // 输出:2 1

    dq.pop_back();    // 尾部删除
    dq.pop_front();   // 头部删除

    return 0;
}

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

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

相关文章

【Pytorch】一文向您详细介绍 torch.sign()

&#x1f389;&#x1f9e0;**【Pytorch】一文向您详细介绍 torch.sign()** 下滑即可查看博客内容 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#xff…

Java高级

类变量/静态变量package com.study.static_; 通过static关键词声明,是该类所有对象共享的对象,任何一个该类的对象去访问他的时候,取到的都是相同的词,同样任何一个该类的对象去修改,所修改的也是同一个对象. 如何定义及访问? 遵循相关访问权限 访问修饰符 static 数据类型…

Day3

首先是模板语句的学习。 在学习之前&#xff0c;我们得搞清楚为什么要学它以及学它有什么用。 Django模板语句&#xff0c;使得网页内容可以动态地从数据库中加载&#xff0c;而不是静态地写在HTML文件中。这样&#xff0c;当你需要更新网站信息时&#xff0c;只需更改模板或…

【Spark计算引擎----第二篇(RDD):一篇文章带你清楚什么是RDD?RDD的概念,RDD的特性,怎么创建一个RDD,RDD的算子】

前言&#xff1a; &#x1f49e;&#x1f49e;大家好&#xff0c;我是书生♡&#xff0c;本阶段和大家一起分享和探索大数据技术Spark—RDD&#xff0c;本篇文章主要讲述了&#xff1a;RDD的概念&#xff0c;RDD的特性&#xff0c;怎么创建一个RDD&#xff0c;RDD的算子等等。欢…

第三十一天 chrome调试工具

打开调试工具 页面空白处右击 检查 或者F12 使用调试工具 ctrl滚轮改变代码大小 左边是html 右边是css css可以直接改动数值左右箭头或者直接输入 查看颜色 ctrl0 复原浏览器大小 点击元素右侧出现样式引入 没有的话 说明类名或者样式引用错误 这里的.new-left是存在的 如果类…

OpenStack;异构算力网络架构;算力服务与交易技术;服务编排与调度技术

目录 OpenStack 一、OpenStack概述 二、OpenStack的主要组件及功能 三、OpenStack的架构 四、OpenStack的应用场景 异构算力网络架构 算力服务与交易技术 服务编排与调度技术 OpenStack 是一个开源的云计算管理平台项目,由NASA(美国国家航空航天局)和Rackspace合作…

数学建模评价类模型—层次分析法(无数据情况下)

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 本文将讲解解决评价类问题的第一种模型层次分析法&#xff08;AHP法&#xff09;&#xff0c;首先我们会具体讲解评价类问题解答的具体流程再对AHP方法进行讲解 一、评价类问题概述 评价…

DB管理客户端navicat、DBever、DbVisualizer数据库连接信息迁移

DB管理客户端Navicat、DBever、DbVisualizer数据库连接信息迁移 第三方数据库连接工具为了确保数据库信息安全通常对保存的数据库连接密码进行加密&#xff0c;填入后想再拿到原文就不可能了&#xff0c;有时交接给别人或者换电脑时可以通过连接数据导出的方式来解决。 Navic…

echarts 极坐标柱状图 如何定义柱子颜色

目录 echarts 极坐标柱状图 如何定义柱子颜色问题描述方式一 在 series 数组中定义颜色方式二 通过 colorBy 和 color 属性配合使用 echarts 极坐标柱状图 如何定义柱子颜色 本文将分享在使用 echarts 的 极坐标柱状图 时&#xff0c;如何自定义柱子的颜色。问题本身并不难解决…

URL中的中文编码与解码

URL在传输时只能使用ACSII码表示&#xff0c;且ASCII码只有128位&#xff0c;无法存储汉字等字符&#xff0c;因此对于这些非ASCII码字符需要进行编码处理&#xff0c;以保证URL的完整性 Python中urllib.parse模块提供了两个方法quote和unquote可用于URL中的中文编码与解码 以…

全网最强Docker教程 | 万字长文爆肝Docker教程

Docker 官方文档地址:https://www.docker.com/get-started 中文参考手册:https://docker_practice.gitee.io/zh-cn/ 1.什么是 Docker 1.1 官方定义 最新官网首页 # 1.官方介绍 - We have a complete container solution for you - no matter who you are and where you ar…

攻防世界-MISC-心仪的公司-wireshark流量分析

心仪的公司 下载后发现是wireshark文件&#xff0c;打开&#xff1a; 源Ip为192.168.1.111 筛选指令&#xff1a; tcp contains"shell" && ip.src192.168.1.111 筛选http流同样能得到flag&#xff1a;

Python兼职接单全攻略:掌握技能,拓宽收入渠道

引言 随着Python在数据处理、Web开发、自动化办公、爬虫技术等多个领域的广泛应用&#xff0c;越来越多的人开始利用Python技能进行兼职接单&#xff0c;以此拓宽收入渠道。本文将详细介绍Python兼职接单的注意事项、所需技能水平、常见单子类型、接单途径及平台&#xff0c;帮…

一文读懂企业数字化涉及的四种架构:业务架构、应用架构、技术架构、数据架构

在当今数字化转型的时代&#xff0c;企业面临着前所未有的挑战与机遇。为了应对这些变化&#xff0c;构建一套高效、灵活且可扩展的企业级架构变得尤为重要。本文将详细介绍 业务架构、应用架构、技术架构 和 数据架构&#xff0c;并结合实际案例进行阐述&#xff0c;帮助读者更…

【MySQL】最左前缀匹配原则

目录 准备库表 结果集在索引列中的查询 1. explain select a,b,c from t where a1; 2. explain select a,b,c from t where a1 AND b2; 3. explain select a,b,c from t where a1 order by b; 4. explain select a,b,c from t where a1 order by d; 5. explain select a…

css 数字平铺布局

效果图 <!DOCTYPE html> <html> <head><meta charset"utf-8"><title>活动中心</title><meta name"viewport" content"maximum-scale1.0,minimum-scale1.0,user-scalable0,widthdevice-width,initial-scale1.0…

团队Bug管理:7个顶级工具帮手

本文将分享2024年值得关注的7款Bug管理工具&#xff1a;PingCode、Worktile、Tower、禅道、Coding、Bugzilla、Jira。 在面对日益复杂的软件开发项目时&#xff0c;管理Bug成为了一个让许多团队头疼的问题。选择一个合适的Bug管理工具不仅可以提高团队的效率&#xff0c;还能显…

Apache IoTDB 论文入选数据库国际顶会 ICDE 2024

近日&#xff0c;Apache IoTDB 的研究成果论文&#xff1a;On Tuning Raft for IoT Workload in Apache IoTDB&#xff08;《在 Apache IoTDB 中针对物联网工作负载调整 Raft 共识协议》&#xff09;被数据库领域国际顶级学术会议 The 40th IEEE International Conference on D…

Netty 必知必会(六)—— 粘包拆包问题

tcp粘包、半包怎么解决的&#xff08;LineBased和LengthBased,我是用的是LineBased&#xff09;为什么要使用LineBased&#xff0c;怎么分割的&#xff08;/r/n&#xff0c;当时没有考虑太多&#xff0c;觉得这个比较简单&#xff09;Netty解决粘包的几种方式Netty 拆包粘包的实…

SD-WAN组网加速ZOOM视频会议

随着远程办公和在线教育的普及&#xff0c;视频会议已成为人们日常沟通的重要工具。然而&#xff0c;网络不稳定、延迟高和带宽不足等问题常常影响ZOOM视频会议的体验。为了有效解决这些问题&#xff0c;SD-WAN组网开始被应用于ZOOM视频会议加速。 那么&#xff0c;SD-WAN具体是…