C++STL之stack和queue容器(详细+通俗易懂)

前言:老铁们好,笔者好久没更新STL的容器了,今天,笔者接着之前的STL容器的内容继续更新,所以今天给老铁们分享的是STL里面的栈和队列的容器的知识。

1.栈的定义

老规矩,我们先来看看C++的官网对stack的介绍文档。
在这里插入图片描述
然后我再为老铁们用大白话解释一下文档里面的内容。

1.在数据结构那一门课程中我们就学过,栈具有后进先出的特点,数据只能从栈顶出入,文档中第一点讲的就是这个。

2.栈是作为容器适配器被实现的,什么是容器适配器呢?容器适配器就像一个"转化器"(比如我们的充电线的接口),它能将现有的容器转化为新的,具有特定功能的东西,例如可以将vector,list…转化为stack

3.底层容器可以是任何容器,只需要满足empty,size,back,push_back,pop_back这些操作即可,如果没有我们自己写的容器,那么会使用标准的容器,例如vector,list…

.

2.stack的使用

我会为老铁们逐一演示stack的常用接口是如何使用的。

首先stack使用,需要包头文件

#include <stack>

栈的定义

stack<int> st;//栈里面数据类型是int型

栈的插入数据

stack<int> st;
//插入1 2 3 4
st.push(1);
st.push(2);
st.push(3);
st.push(4);

栈数据的遍历

这里需要注意一下,栈是没有迭代器的,那么我们该如何遍历栈里面的数据呢?

stack<int> st;
//插入1 2 3 4
st.push(1);
st.push(2);
st.push(3);
st.push(4);while (!st.empty())//判断栈里面的数据不为空
{int top = st.top();//取栈顶的数据st.pop();//删除该数据,让栈顶的数据进行迭代cout << top << endl;
}

代码的预期结果应该是4 3 2 1,那么我们来看看结果吧
在这里插入图片描述
结果正确!以上这些结果就是stack里面常用的接口了。

3.队列的定义

还是老规矩,我们先来看看c++官网文档对queue的介绍文档。
在这里插入图片描述

1.队列也是一种容器适配器,队列满足先进先出的性质,队列从队头出数据,从队尾入数据。

2.如果底层容器是我们自己设计的话,需要满足以下功能接口,empty,size,front,back,push_back,pop_front。

4.队列的使用

queue的使用和stack的使用一样,都是要包头文件

#include <queue>

队列的定义

queue<int> q;

队列的插入数据

queue<int> q;
q.push(1);
q.push(2);
q.push(3);
q.push(4);

队列中数据的遍历

queue也是没有迭代器的,所以queue的遍历操作和stack的遍历操作差不多

	queue<int> q;q.push(1);q.push(2);q.push(3);q.push(4);while (!q.empty()){int top = q.front();//取队头的数据cout << top << " ";q.pop();//让队头进行迭代}

代码的预期结果应该是1 2 3 4,那么我们来看看是不是这样
在这里插入图片描述

取队尾的元素

queue<int> q;
q.push(1);
q.push(2);
q.push(3);
q.push(4);cout << q.back() << endl;

在这里插入图片描述

求队列元素的个数

queue<int> q;
q.push(1);
q.push(2);
q.push(3);
q.push(4);cout << q.size() << endl;

在这里插入图片描述

5.stack的模拟实现

通过以上的知识,我们已经懂得了栈和队列的使用了,那么接下来,我们需要模拟栈和队列的实现了。

首先,我们需要定义一个命名空间,防止和库里面的冲突

namespace ljy
{}

再声明模板(不懂得可以看模板那一篇博客)

//T表示stack里面数据的类型,Container表示底层的容器
template<class T,class Container>

再定义类模板和声明底层容器的对象

template<class T,class Container>//T表示stack里面数据的类型,Container表示底层的容器
class stack
{
private:Container _con;//声明底层容器的对象
};

实现插入接口

public:void push(const T& x){_con.push_back(x);//调用底层容器的插入数据的接口}

实现删除栈顶数据的接口

void pop()
{_con.pop_back();//调用底层容器的删掉数据的接口
}

实现求栈的大小

size_t size()
{return _con.size();//调用底层容器的求数据个数的接口
}

实现栈判空

bool empty()
{return _con.empty();//调用底层容器的判断是否为空的接口
}

实现取栈顶的数据

T& top()
{return _con.back();//栈是后进先出
}

测试代码1

void test_stack1(){//定义一个栈,底层容器是数组stack<int, vector<int>> st1;st1.push(1);st1.push(2);st1.push(3);while (!st1.empty()){int top = st1.top();cout << top << " ";st1.pop();}cout << endl;}

执行代码看看有没有问题

#include "stack.h"
int main()
{ljy::test_stack1();return 0;
}

在这里插入图片描述

测试代码2

void test_stack2()
{//定义一个栈,底层容器是数组//stack<int, vector<int>> st1;//定义一个栈,底层容器是链表stack<int, list<int>> st1;st1.push(1);st1.push(2);st1.push(3);while (!st1.empty()){int top = st1.top();cout << top << " ";st1.pop();}cout << endl;
}
#include "stack.h"
int main()
{ljy::test_stack2();return 0;
}

在这里插入图片描述

结论:无论是数组还是链表都可以作为底层容器来模拟实现栈,所以可以推导出栈就是一个容器适配器!!!

6.queue模拟实现

queue的模拟实现和stack的模拟实现非常相似,只是队尾入,队头出而已。

#pragma once
#include <iostream>
#include <list>
#include <vector>
using namespace std;namespace ljy
{template<class T, class Container>//T表示queue里面数据的类型,Container表示底层的容器class queue{public:void push(const T& x)//队尾入{_con.push_back(x);//调用底层容器的插入数据的接口}void pop()//队头出{_con.pop_front();//调用底层容器的删掉数据的接口}size_t size(){return _con.size();//调用底层容器的求数据个数的接口}bool empty(){return _con.empty();//调用底层容器的判断是否为空的接口}T& front()//取队头数据{return _con.front();//队列是先进先出}T& back()//取队尾数据{return _con.back();//队列是先进先出}private:Container _con;};
}

测试代码

void test_queue()
{queue<int, vector<int>> q;q.push(1);q.push(2);q.push(3);q.push(4);while (!q.empty()){cout << q.front() << " ";q.pop();}cout << endl;
}

看一下运行结果有没有问题
在这里插入图片描述
直接报错了,我们看看报错内容,是头删出问题了,我们知道vector是不支持头删了,因为vector头删需要挪动数据,效率太低了,由于我们实现queue底层是使用vector容器,所有就直接报错了,我们把vector换成list看还有没有问题。

#pragma once
#include <iostream>
#include <list>
#include <vector>
using namespace std;namespace ljy
{template<class T, class Container>//T表示queue里面数据的类型,Container表示底层的容器class queue{public:void push(const T& x)//队尾入{_con.push_back(x);//调用底层容器的插入数据的接口}void pop()//队头出{_con.pop_front();//调用底层容器的删掉数据的接口}size_t size(){return _con.size();//调用底层容器的求数据个数的接口}bool empty(){return _con.empty();//调用底层容器的判断是否为空的接口}T& front()//取队头数据{return _con.front();//队列是先进先出}T& back()//取队尾数据{return _con.back();//队列是先进先出}private:Container _con;};void test_queue(){queue<int, list<int>> q;q.push(1);q.push(2);q.push(3);q.push(4);while (!q.empty()){cout << q.front() << " ";q.pop();}cout << endl;}
}

在这里插入图片描述
换成list就没问题了

7.deque容器

老规矩,我们先来看看有关deque容器的文档。
在这里插入图片描述
deque叫双端队列,但它不是队列,而是一种双开口,连续的空间的数据结构,那什么是双开口呢?双开口就是可以在头和在尾插入和删除数据,那么deque相比于vector效率就高很多了,deque相比于list空间的利用率较高。
在这里插入图片描述

deque的缺点

我们知道C++是一门极度注重效率的语言,deque虽然结合了list和vector的优点,但是deque并没有完全继承二者的优点,相比于二者各自的优点还是差点意思,所以deque代替不了vector和list
我们可以看看deque的随机访问和vector随机访问相差的时间
在这里插入图片描述

总结

以上就是关于STL中的stack和queue的全部内容,希望各位老铁看了这篇文章能有所收获。

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

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

相关文章

Kafka 压缩算法详细介绍

文章目录 一 、Kafka 压缩算法概述二、Kafka 压缩的作用2.1 降低网络带宽消耗2.2 提高 Kafka 生产者和消费者吞吐量2.3 减少 Kafka 磁盘存储占用2.4 减少 Kafka Broker 负载2.5 降低跨数据中心同步成本 三、Kafka 压缩的原理3.1 Kafka 压缩的基本原理3.2. Kafka 压缩的工作流程…

C# 语言基础全面解析

.NET学习资料 .NET学习资料 .NET学习资料 一、引言 C# 是一种功能强大、面向对象且类型安全的编程语言&#xff0c;由微软开发&#xff0c;广泛应用于各种类型的软件开发&#xff0c;从桌面应用、Web 应用到游戏开发等领域。本文将全面介绍 C# 语言的基础知识&#xff0c;帮…

实战:利用百度站长平台加速网站收录

本文转自&#xff1a;百万收录网 原文链接&#xff1a;https://www.baiwanshoulu.com/33.html 利用百度站长平台加速网站收录是一个实战性很强的过程&#xff0c;以下是一些具体的步骤和策略&#xff1a; 一、了解百度站长平台 百度站长平台是百度为网站管理员提供的一系列工…

DNS缓存详解(DNS Cache Detailed Explanation)

DNS缓存详解 清空DNS缓存可以让网页访问更快捷。本文将从什么是DNS缓存、为什么清空DNS缓存、如何清空DNS缓存、清空DNS缓存存在的问题四个方面详细阐述DNS缓存清空的相关知识。 一、什么是DNS缓存 1、DNS缓存的定义&#xff1a; DNS缓存是域名系统服务在遇到DNS查询时自动…

数组排序算法

数组排序算法 用C语言实现的数组排序算法。 排序算法平均时间复杂度最坏时间复杂度最好时间复杂度空间复杂度是否稳定适用场景QuickO(n log n)O(n)O(n log n)O(log n)不稳定大规模数据&#xff0c;通用排序BubbleO(n)O(n)O(n)O(1)稳定小规模数据&#xff0c;教学用途InsertO(n)…

快速更改WampServer根目录php脚本

快速更改WampServer根目录php脚本 <?php // 配置文件地址 $apacheConfPath C:\Install\CTF\Wampserver\bin\apache\apache2.4.62.1\conf\httpd.conf; $apacheConfPath2 C:\Install\CTF\Wampserver\bin\apache\apache2.4.62.1\conf\extra\httpd-vhosts.conf; // 新根目录…

OFDM系统仿真

1️⃣ OFDM的原理 1.1 介绍 OFDM是一种多载波调制技术&#xff0c;将输入数据分配到多个子载波上&#xff0c;每个子载波上可以独立使用 QAM、PSK 等传统调制技术进行调制。这些子载波之间互相正交&#xff0c;从而可以有效利用频谱并减少干扰。 1.2 OFDM的核心 多载波调制…

第11章:根据 ShuffleNet V2 迁移学习医学图像分类任务:甲状腺结节检测

目录 1. Shufflenet V2 2. 甲状腺结节检测 2.1 数据集 2.2 训练参数 2.3 训练结果 2.4 可视化网页推理 3. 下载 1. Shufflenet V2 shufflenet v2 论文中提出衡量轻量级网络的性能不能仅仅依靠FLOPs计算量&#xff0c;还应该多方面的考虑&#xff0c;例如MAC(memory acc…

.Net WebAPI -[HttpPut(“{fileServiceId:int}“)]

[HttpPut("{fileServiceId:int}")] 这个写法是 ASP.NET Core 中的一个路由特性&#xff0c;用于定义一个 HTTP PUT 请求的路由&#xff0c;并指定路由参数的类型。 解析 HttpPut [HttpPut]&#xff1a; 这是一个 ASP.NET Core 的路由特性&#xff0c;用于标记一个方…

【C语言】内存管理

【C语言】内存管理 文章目录 【C语言】内存管理1.概念2.库函数3.动态分配内存malloccalloc 4.重新调整内存的大小和释放内存reallocfree 1.概念 C 语言为内存的分配和管理提供了几个函数。这些函数可以在 <stdlib.h> 头文件中找到。 在 C 语言中&#xff0c;内存是通过…

网络编程套接字(中)

文章目录 &#x1f34f;简单的TCP网络程序服务端创建套接字服务端绑定服务端监听服务端获取连接服务端处理请求客户端创建套接字客户端连接服务器客户端发起请求服务器测试单执行流服务器的弊端 &#x1f350;多进程版的TCP网络程序捕捉SIGCHLD信号让孙子进程提供服务 &#x1…

happytime

happytime 一、查壳 无壳&#xff0c;64位 二、IDA分析 1.main 2.cry函数 总体&#xff1a;是魔改的XXTEA加密 在main中可以看到被加密且分段的flag在最后的循环中与V6进行比较&#xff0c;刚好和上面v6数组相同。 所以毫无疑问密文是v6. 而与flag一起进入加密函数的v5就…

DIFY源码解析

偶然发现Github上某位大佬开源的DIFY源码注释和解析&#xff0c;目前还处于陆续不断更新地更新过程中&#xff0c;为大佬的专业和开源贡献精神点赞。先收藏链接&#xff0c;后续慢慢学习。 相关链接如下&#xff1a; DIFY源码解析

Electricity Market Optimization 探索系列(一)

​ 本文参考链接&#xff1a;Linear Programming Mini Example 先从一个线性规划的例子说起&#xff1a; 问题背景&#xff1a; 现在需要使用两台发电机满足用户的用电需求&#xff0c;发电机一的发电功率上限是 6MW&#xff0c;发电机二的发电功率上限是 4MW&#xff0c;发电…

Spring的AOP思想中事物管理注意点

我们以事务管理实现AOP思想 通过在Service层加入事务管理,因为Service层可能使用多个DAO(多条SQL语句) 要保证这些SQL要么同时成功,要么同时失败,例如:学生Serivce:删除学生的时候,还需要删除学生关联信息(选课信息) 只有都删除成功才提交,如果有一条执行失败…

Hot100之子串

560和为K的子数组 题目 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列 思路解析 ps&#xff1a;我们的presum【0】就是0&#xff0c;如果没有这个0的话我们的第一个元素就无法减去上…

网络工程师 (11)软件生命周期与开发模型

一、软件生命周期 前言 软件生命周期&#xff0c;也称为软件开发周期或软件开发生命周期&#xff0c;是指从软件项目的启动到软件不再被使用为止的整个期间。这个过程可以细分为多个阶段&#xff0c;每个阶段都有其特定的目标、任务和产出物。 1. 问题定义与需求分析 问题定义…

谈谈你所了解的AR技术吧!

深入探讨 AR 技术的原理与应用 在科技飞速发展的今天&#xff0c;AR&#xff08;增强现实&#xff09;技术已经悄然改变了我们与周围世界互动的方式。你是否曾想象过如何能够通过手机屏幕与虚拟物体进行实时互动&#xff1f;在这篇文章中&#xff0c;我们将深入探讨AR技术的原…

【Linux】使用管道实现一个简易版本的进程池

文章目录 使用管道实现一个简易版本的进程池流程图代码makefileTask.hppProcessPool.cc 程序流程&#xff1a; 使用管道实现一个简易版本的进程池 流程图 代码 makefile ProcessPool:ProcessPool.ccg -o $ $^ -g -stdc11 .PHONY:clean clean:rm -f ProcessPoolTask.hpp #pr…

MYSQL--一条SQL执行的流程,分析MYSQL的架构

文章目录 第一步建立连接第二部解析 SQL第三步执行 sql预处理优化阶段执行阶段索引下推 执行一条select 语句中间会发生什么&#xff1f; 这个是对 mysql 架构的深入理解。 select * from product where id 1;对于mysql的架构分层: mysql 架构分成了 Server 层和存储引擎层&a…