STL —— stack、queue

图片名称

 
博主首页: 有趣的中国人
 
专栏首页: C++专栏
 

目录

 1. 容器适配器

2. 栈的模拟实现

3. 队列的模拟实现

4. 双端队列deque 

4.1 deque的原理介绍

 4.2 deque的缺陷

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


本篇文章主要讲解  stack 和 queue  的相关内容

 std::stack 是一个模板类,定义在 <stack> 头文件中,它基于其他的底层容器来实现栈的功能。默认情况下,std::stack 使用 std::deque 作为其底层容器,但也可以使用其他 STL 容器,如 std::vectorstd::list

基本操作

  1. 压入元素: 使用 push() 成员函数将元素推入栈顶。

  2. 弹出元素: 使用 pop() 成员函数从栈顶移除元素。

  3. 访问栈顶元素: 使用 top() 成员函数获取栈顶元素的引用,但不会将其从栈中移除。

  4. 判断栈是否为空: 使用 empty() 成员函数检查栈是否为空。

  5. 获取栈的大小: 使用 size() 成员函数获取栈中元素的数量。

std::queue 是一个模板类,定义在 <queue> 头文件中,它基于其他的底层容器来实现队列的功能。默认情况下,std::queue使用 std::queue 作为其底层容器,但也可以使用其他 STL 容器,如 std::list

基本操作

  1. 入队操作: 使用 push() 成员函数将元素推入队列的末尾。

  2. 出队操作: 使用 pop() 成员函数从队列的头部移除元素。

  3. 访问队列头部元素: 使用 front() 成员函数获取队列头部元素的引用,但不会将其从队列中移除。

  4. 访问队列尾部元素: 使用 back() 成员函数获取队列尾部元素的引用,但不会将其从队列中移除。

  5. 判断队列是否为空: 使用 empty() 成员函数检查队列是否为空。

  6. 获取队列的大小: 使用 size() 成员函数获取队列中元素的数量。


 1. 容器适配器

如果按照正常的思路实现stack,那么其中的元素应该有:

class stack
{private:int _top;int _size;int _capacity;
};

但是,在C++中,用了适配器的模式,何为适配器呢?

我们知道stack模拟实现的过程与vector类似,那我们能否用vector来实现stack呢?

肯定是可以的,容器适配器是一种设计模式,它提供了一种简单的方式来修改或扩展现有容器的接口,以满足特定的需求或限制。


2. 栈的模拟实现

我们在实现栈的时候就可以用到容器适配器的模式,只需要在传模板参数的时候多加一个参数即可:

template<class T, class Container = vector<T>>
class stack
{
public:void push(const T& val){_con.push_back(val);}void pop(){_con.pop_back();}size_t size() const{return _con.size();}bool empty(){return _con.empty();}T& top(){return _con.back();}
private:Container _con;
};
void stack_test1()
{stack<int> st;st.push(1);st.push(2);st.push(3);st.push(4);st.push(5);while (!st.empty()){cout << st.top() << " ";st.pop();}cout << endl;
}


3. 队列的模拟实现

类似的,我们可以用容器适配器来模拟实现队列:

template<class T, class Container = vector<T>>
class stack
{
public:void push(const T& val){_con.push_back(val);}void pop(){_con.pop_back();}size_t size() const{return _con.size();}bool empty(){return _con.empty();}T& top(){return _con.back();}
private:Container _con;
};
void stack_test1()
{stack<int> st;st.push(1);st.push(2);st.push(3);st.push(4);st.push(5);while (!st.empty()){cout << st.top() << " ";st.pop();}cout << endl;
}


4. 双端队列deque 

4.1 deque的原理介绍

deque(双端队列):是一种双开口的"连续"空间的数据结构,双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比较高。
 

deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际deque类似于一个动态的二维数组,其底层结构如下图所示:


双端队列底层是一段假想的连续空间,实际是分段连续的,为了维护其“整体连续”以及随机访问的假象,落在了deque的迭代器身上,因此deque的迭代器设计就比较复杂,如下图所示:


那deque是如何借助其迭代器维护其假想连续的结构呢?


 4.2 deque的缺陷

vector比较,deque的优势是:头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不需要搬移大量的元素,因此其效率是必vector高的。


list比较,其底层是连续空间,空间利用率比较高,不需要存储额外字段。


但是,deque有一个致命缺陷:不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到某段小空间的边界,导致效率低下,而序列式场景中,可能需要经常遍历,因此在实际中,需要线性结构时,大多数情况下优先考虑vectorlistdeque的应用并不多,而目前能看到的一个应用就是,STL用其作为stackqueue的底层数据结构

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

stack是一种后进先出的特殊线性数据结构,因此只要具有push_back()pop_back()操作的线性结构,都可以作为stack的底层容器,比如vectorlist都可以;queue是先进先出的特殊线性数据结构,只要具有push_backpop_front操作的线性结构,都可以作为queue的底层容器,比如list。但是STL中对stackqueue默认选择deque作为其底层容器,主要是因为:

  1. stackqueue不需要遍历(因此stackqueue没有迭代器),只需要在固定的一端或者两端进行操作。
  2. stack中元素增长时,dequevector的效率高(扩容时不需要搬移大量数据);queue中的元素增长时,deque不仅效率高,而且内存使用率高。结合了deque的优点,而完美的避开了其缺陷.。

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

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

相关文章

SSH安全设置

今天发现自己的公有云服务器被攻击了 然后查看了登录日志&#xff0c;如上图 ls -sh /var/log/secure vim /var/log/secure然后增加了安全相关的设置 具体可以从以下方面增加安全性&#xff1a; 修改默认SSH端口公有云修改安全组策略及防火墙端口设置登录失败次数锁定用户及限…

✯✯✯宁波 IATF16949 认证:助力汽车企业迈向卓越✯✯✯

&#x1f308;&#x1f308;&#x1f308;宁波IATF16949认证&#xff1a;&#x1f49d;助力汽车企业迈向卓越&#x1f497; &#x1f575;️‍♂️宁波&#xff0c;这座繁华的&#x1f98a;港口城市&#xff0c;不仅以其&#x1f42f;独特的地理位置和丰富的&#x1f54a;️历史…

Unity开发HoloLens2应用时,用VisualStudio进行真机在线Debug调试

一、需求 用Unity开发的应用&#xff0c;部署到真机设备出现启动崩溃&#xff0c;此时可以用在线调试&#xff0c;排查错误。 二、开发环境说明 MRholoLens2 Unity 2021.3.18 Win Win10 VS vs2022 三、调试操作步骤 1、HoloLens2与电脑的连接&#xff0c;Wifi连接&…

【C++从练气到飞升】07---内存管理

&#x1f388;个人主页&#xff1a;库库的里昂 ✨收录专栏&#xff1a;C从练气到飞升 &#x1f389;鸟欲高飞先振翅&#xff0c;人求上进先读书。 目录 一、 C/C内存分布 二、 C语言中动态内存管理方式 三、 C中动态内存管理 1. new/delete操作内置类型 2. new和delete操作…

Mac用户必备神器:Default Folder X,让文件操作更快捷、更智能!

Default Folder X for Mac是一款功能强大的文件管理辅助工具&#xff0c;它为Mac用户带来了前所未有的文件操作体验。&#x1f31f; 无论是日常办公、学习还是娱乐&#xff0c;Default Folder X都能帮助你更高效地管理文件&#xff0c;让你的工作更加得心应手。&#x1f4bc; …

面试手撕合集

82.删除排序链表中的重复元素II 定义单个指针 cur&#xff0c;指向虚拟头节点。如果 cur.next cur.next.next&#xff0c;说明 cur 后面的两个节点重复&#xff0c;例如 节点2 后面存在 2个节点3。我们令 节点2 -> 节点4&#xff0c;实现删除两个节点3的操作。 class Solut…

哪个牌子的电视盒子好用?经销商整理线下热销电视盒子排行榜

在选购电视盒子的时候许多朋友并不了解哪个牌子的电视盒子好用&#xff0c;如何才能买到最满意的电视盒子呢&#xff1f;我身为数码实体店老板&#xff0c;做电视盒子这块有七年了&#xff0c;经常会有用户问我电视盒子相关问题&#xff0c;我按照店内销量整理了电视盒子排行榜…

Linux标准c库操作(4.15)

fopen函数“const char *mode”参数选项。 结果&#xff1a; 标准库c写入结构体到文件&#xff1a; #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <string.h> #in…

【Linux】磁盘扩容到根目录逻辑卷(LVM)

目录 一、物理卷和逻辑卷 1.物理卷和逻辑卷的区别 2.在Linux系统中查看所有物理卷的信息 3.在Linux系统中查看所有逻辑卷的信息 二、文件系统 三、实操-对root&#xff08;/&#xff09;目录进行扩容 1.使用lsblk命令查看新加入的磁盘信息 2.fdisk -l命令查看系统中磁盘…

FFmpeg: 自实现ijkplayer播放器--05ijkplayer–连接UI界面和ffplay.c

文章目录 ijkplayer时序图消息循环--回调函数实现播放器播放时状态转换播放停止ijkmediaPlay成员变量成员函数ijkplayer时序图 stream_open: frame_queue_init packet_queue_init init_clock 创建read_thread线程 创建video_refresh_thread线程 消息循环–回调函数实现 ui 和…

Spring Boot 2.x 将 logback 1.2.x 升级至 1.3.x

场景 安全部门针对代码进行漏洞扫描时&#xff0c;发现 logback-core 和 logback-classic 都属于 1.2.x 版本&#xff0c;这个版本存在 CVE 漏洞&#xff0c;并且建议升级到 1.3.x 版本。 问题 将两个包直接升级到 1.3.x 版本时&#xff0c;Spring Boot Web 服务启动直接出现…

【解决】Spring Boot创建项目常见问题

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;Spring学习之路&#x1f4d5;格言&#xff1a;吾愚多不敏&#xff0c;而愿加学欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 idea无maven选项 无效发行版17 类⽂件具有错误的版本 61.0, 应为 …