【C++杂货铺】详解 stack 和 queue

25 篇文章 2 订阅
订阅专栏


🌈前言🌈

        欢迎收看本期【C++杂货铺】,本期内容将讲解C++STL中stack和queue的内容,其中包含了stack , queue,priority_queue是什么,怎么使用以及模拟实现这些容器。

        此外,还将将讲解设计模式中的适配器模式,以及STL中stack,queue的底层deque。

📁 stack 介绍和使用

 📂 介绍

        stack是一种容器适配器,专门用于具有先进后出的上下文环境,只能从容器的一端进行元素的插入和提取操作。

        stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定的成员函数来访问其元素,将特定类作为其底层,元素特定容器的尾部被压入和弹出。

        stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持一下操作:

        ● empty : 判空操作。

        ● back:获取尾部元素操作。

        ● push_back:尾部插入元素操作。

        ● pop_back:尾部删除元素操作。

        标准容器vector,deque,list均符合这些需求,默认情况下,如果没有stack指定特定的底层容器,默认情况下使用deque。

📂 使用

stack - C++ Reference (cplusplus.com)

#include <iostream>
#include <stack>

using namespace std;

int main()
{
    stack<int> st;

    st.push(1);
    st.push(2);
    st.push(3);

    while(!st.empty())
    {
        cout<<st.top()<<" ";
        st.pop();    
    }
    cout<<endl;
}

 📂 模拟实现

#include<deque>
namespace exercise
{
 template<class T, class Con = deque<T>>
 class stack
 {
 public:
     stack() {}
     void push(const T& x) {_c.push_back(x);}
     void pop() {_c.pop_back();}
     T& top() {return _c.back();}
     const T& top()const {return _c.back();}
     size_t size()const {return _c.size();}
     bool empty()const {return _c.empty();}
 private:
     Con _c;
 };
}

📁 queue 介绍和使用

 📂 介绍

        队列也是一种容器适配器,专门用于先进先出的操作,其中从容器一端插入元素,另一端提取元素。

        队列作为容器适配器实现,容器适配器将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素,元素从队尾入队列,从队头出队列。

        底层容器可以是变化尊模板容器类模板之一,也可以是其他专门设计的容器类,该底层容器应该支持一下操作:

        ● empty : 检测队列是否为空。

        ● size : 返回队列中有效元素的个数。

        ● front : 返回队头元素的引用。

        ● back:返回队尾元素的引用。

        ● push_back:在队列尾部入队列。

        ● pop_back:在队列头部出队列。

        标准容器类deque和list满足这些要求,默认情况下,如果没有为queue实例化指定容器类,则使用标准容器deque。

 📂 使用

queue - C++ Reference (cplusplus.com)

#include <iostream>
#include <queue>

using namespace std;

int main()
{
    queue<int> q;

    q.push(1);
    q.push(2);
    q.push(3);

    while(!q.empty())
    {
        cout<<q.front()<<" ";
        q.pop();
    }
    cout<<endl;
    
    return 0;
}

 📂 模拟实现

#include <deque>
#include <list>
namespace exercise
{
 template<class T, class Con = deque<T>>
 //template<class T, class Con = list<T>>
 class queue
 {
 public:
     queue() {}
     void push(const T& x) {_c.push_back(x);}
     void pop() {_c.pop_front();}
     T& back() {return _c.back();}
     const T& back()const {return _c.back();}
     T& front() {return _c.front();}
     const T& front()const {return _c.front();}
     size_t size()const {return _c.size();}
     bool empty()const {return _c.empty();}
 private:
     Con _c;
 };
}

📁 priority_queue 介绍和使用

 📂 介绍

        优先队列也是一种容器适配器,根据严格的若排序标准,它的第一个元素总是它所包含元中最大的。

        本质上优先队列就是堆,在堆中可以随时插入元素,并且只能检索最大/小元素(优先队列中位于顶部的元素)。

        容器适配器将特定容器类封装为底层容器类,priority_queue提供一组特定的成员函数来访问其元素。元素从特定容器的尾部弹出,其称为优先队列的顶部。

        底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类,容器应该是可以通过随机访问迭代器访问,支持以下操作:

        ● empty : 检测容器是否为空。

        ● size : 返回容器中有效元素的个数。

        ● front : 返回容器第一个元素的引用。

        ● push_back:在容器尾部插入元素。

        ● pop_back:删除容器尾部元素。

        标准容器类vector和deque满足这些需求。默认情况下,使用vector作为底层容器类。

        需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数来自动完成操作。

 📂 使用

#include <iostream>
#include <queue>

using namespace std;

int main()
{
    //默认建大堆
    //等价于 priority_queue<int,vector<int>,less<int>>
    priority_queue<int> p1;    

    //传递仿函数 , 建小堆
    priority_queue<int,vector<int>,greater<int>> p2;

    p1.push(1);
    p1.push(2);
    p1.push(3);

    p2.push(3);
    p2.push(2);
    p2.push(1);

    //p1 : 3,2,1
    //p2 : 1,2,3
}

 📂 仿函数

        仿函数(Functor)是一种行为类似于函数的对象。在C++中,仿函数可以被当作函数使用,可以执行函数调用操作,并且可以具有自己的状态。

        通常情况下,仿函数是一个类,它重载了函数调用运算符operator()。通过重载该运算符,仿函数可以像函数一样被调用,接受参数并返回结果。重载了operator[]的类,就是仿函数。

        仿函数的对象可以像函数一样调用。

        仿函数可以控制比较逻辑,控制如何比较。

 📂 模拟实现

namespace exercise
{
	template <class T>
	struct less
	{
		bool operator()(const T& x, const T& y)
		{
			return x < y;
		}
	};

	template<class T>
	struct greater
	{
		bool operator()(const T& x, const T& y)
		{
			return  x > y;
		}
	};

	template<class T,class Container = vector<T>,class Compare = less<T>>
	class priority_queue
	{
	public:

		void AdjustUp(int child)
		{
			Compare com;
			int parent = (child - 1) / 2;
			while (child > 0)
			{
				//if (_con[child] > _con[parent])
				if(com(_con[parent],_con[child]))
				{
					std::swap(_con[child], _con[parent]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}

		void push(const T& val)
		{
			_con.push_back(val);
			AdjustUp(_con.size() - 1);
		}

		void AdjustDown(int parent)
		{
			Compare com;

			int child = parent * 2 + 1;
			while (child < _con.size())
			{
				if (child + 1 < _con.size() && com(_con[child], _con[child + 1]))
				{
					child++;
				}

				if (com(_con[parent], _con[child]))
				{
					std::swap(_con[child],_con[parent]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
				{
					break;
				}
			}
		}

		void pop()
		{
			std::swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();
			AdjustDown(0);
		}

		size_t size()
		{
			return _con.size();
		}

		bool empty()
		{
			return _con.empty();
		}

		const T& top()
		{
			return _con[0];
		}

	private:
		Container _con;
	};

}

📁 容器适配器

 📂 概念

        适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。

 📂 STL库中stack和queue的底层结构

        虽然stack和queue中也可以存放元素,但在STL中并没有讲其划分为容器行列,而是将其称为容器适配器,这是因为stack和queue只是堆其他容器的接口进行包装,STL中stack和queue默认使用deque。

 📂 deque介绍

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

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

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

        deque的缺陷:

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

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

        但是deque有一个致命缺陷,不适合遍历,因为在遍历时,deque的迭代器要频繁的区间所是否移动到某段小空间的边界,导致效率低下,在序列式场合中,肯呢个需要经常遍历,因此在实际中,需要线性结构时,大多数有限考虑vector和list,deque的应用不多,目前的一个应用就是.STL用其为stack和queue的底层容器类。

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

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

        1. stack和queue不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或者两端进行操作。

         2. 在stack中元素增长时,deque比vector的效率高(扩容时不需要搬移大量数据);queue中的元素增长 时,deque不仅效率高,而且内存使用率高。

        结合了deque的优点,而完美的避开了其缺陷。

📁 总结

        以上,就是本期【C++杂货铺】stack和queue的主要内容了,包含了它stack,queue,priority_queue的介绍和使用方法,以及他们模拟实现他们的底层。

        此外,还介绍了仿函数是什么,就是一个冲在了operator()的类,使用它的对象就像使用函数一样。

        如果感觉本期内容对你有帮助,欢迎点赞,收藏,关注。Thanks♪(・ω・)ノ

C++ STL容器stackqueue详解
09-01
主要介绍了C++ STL容器stackqueue详解的相关资料,需要的朋友可以参考下
资料收集整理
zhaoxinglin123的专栏
01-19 216
1、jvm 2、java 3、spring 4、mysql 5、redis 6、kafka 7、hadoop 8、算法 9、思考
Java面试题(140多道高频面试题2023版)
记录开发中常见的问题以及技术等
06-20 1万+
持续更新中.....
Java面试题大全(2021版)
热门推荐
Java笔记
11-25 29万+
发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全,希望对大家有帮助哈~ 本套Java面试题大全,全的不能再全,哈哈~ 一、Java基础知识面试题 1、Java概述 ①. 何为编程 编程就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程。 为了使计算机能够理解人的意图,人类就必须要将需解决的问题的思路、方法、和手段通过计算机能够理解的形式告诉计算机,使得计算机能够根据人的指令一步一步去工作,完成某种特定的任务。这种人和计算机
Java面试题集锦
fouher的博客
07-21 334
一、Java基础知识面试题 1、Java概述 ①. 何为编程 编程就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程。 为了使计算机能够理解人的意图,人类就必须要将需解决的问题的思路、方法、和手段通过计算机能够理解的形式告诉计算机,使得计算机能够根据人的指令一步一步去工作,完成某种特定的任务。这种人和计算机之间交流的过程就是编程。 ②. 什么是Java Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语
637道Java面试题(含答案)
跑码场
03-01 1469
637道Java面试题(含答案),涵盖Java基础、Java并发、Spring、Spring Boot等多方面面试要点
Java基础知识面试题
裸奔的蜗 牜的博客
02-03 1882
一、Java基础知识面试题 1、Java概述 ①. 何为编程 编程就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程。 为了使计算机能够理解人的意图,人类就必须要将需解决的问题的思路、方法、和手段通过计算机能够理解的形式告诉计算机,使得计算机能够根据人的指令一步一步去工作,完成某种特定的任务。这种人和计算机之间交流的过程就是编程。 ②. 什么是Java Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因
【并发编程系列】并发编程进阶
檀越的博客
02-23 380
juc 是 java.util.concurrent 的简称,为了支持高并发任务,在编程时可以有效减少竞争条件和死锁线程.juc 主要包含 5 大工具包工具包描述locks- ReentrantLock: 独占锁,同一时间只能被一个线程获取,支持重入性。- ReentrantReadWriteLock: 读写锁,ReadLock 是共享锁,WriteLock 是独占锁。- LockSupport: 提供阻塞和解除阻塞线程的功能,不会导致死锁。executor。
C++ stackqueue笔记
02-22
C++ stackqueue笔记
C++stackqueue、vector的用法详解
08-29
本文通过实例代码给大家介绍了C++stackqueue、vector的用法,需要的朋友参考下吧
c++stackqueue和vector的基本操作示例
08-29
主要给大家介绍了关于c++stackqueue和vector基本操作的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面跟着小编来一起学习学习吧。
Linux学习C语言版 LED 灯实验
qq_44219883的博客
05-10 548
大部分情况下都是使用 C 语言去编写的。只是在开始部分用汇编来初始化一下 C 语言环境,比如初始化 DDR、设置堆栈指针 SP 等等,当这些工作都做完以后就可以进入 C 语言环境,也就是运行 C 语言代码,一般都是进入 main 函数。所以我们有两部分文件要做:①、汇编文件汇编文件只是用来完成 C 语言环境搭建。②、C 语言文件C 语言文件就是完成我们的业务层代码的,其实就是我们实际例程要完成的功能。
C++ STL的锁介绍
05-07 230
C++ STL的锁介绍
C++ list 介绍
2301_77203593的博客
05-08 642
构造空list构造可包含n个T类型数据的list构造list,用first到last区间中的元素构造。注意可以是别的容器中的元素。(例如可以用vectorint<int>int中的一段数据构造一个新的listint<int>int。还可以用string等等)。拷贝构造。用已有的一个list构造新的list。注:前提是原链表和链表x都为有序链表,默认升序。将有序链表x按照默认的升序合并至原链表中,合并后x变为空链表。
C++】set与map的使用
2302_76142697的博客
05-03 1000
了解stl库中关联式容器set与map的基础用法。
C++学习第二十八课:C++ 中的智能指针详解
最新发布
2401_84585615的博客
05-10 645
智能指针是一种对象,它可以像常规指针一样使用,但具有自动管理内存的功能。当智能指针离开其作用域时,它会自动删除所指向的对象,从而避免内存泄漏。和。
数组折半法查找数据(C语言
m0_67184754的博客
05-07 160
【代码】数组折半法查找数据(C语言
C++处理栅格数据
天波风客的博客
05-06 346
实验教学:栅格数据处理实验目的:使用C++语言处理栅格数据。我们将涵盖栅格数据的读取、基本操作和简单的空间分析。实验环境:操作系统:Windows/Linux开发环境:Visual Studio/Code::Blocks等依赖库:GDAL(Geospatial Data Abstraction Library)、OpenCV(Open Source Computer Vision Library)...
C++queue输入stack
03-07
可以使用两个队列来实现一个栈,具体实现方法可以参考以下步骤: 1. 定义两个队列 queue1 和 queue2,其中 queue1 用于存储栈中的元素,queue2 用于辅助操作。 2. 入栈操作时,将元素插入到 queue1 的队尾。 3. 出栈操作时,将 queue1 中的元素依次出队并插入到 queue2 的队尾,直到 queue1 中只剩下一个元素,然后将该元素出队即可。 4. 在出队操作时,需要将 queue1 和 queue2 交换,以便下一次操作。 需要注意的是,如果 queue1 和 queue2 中都没有元素时,出栈操作会导致错误,需要进行特殊处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • Linux基本命令操作 —— 文件夹/文件的创建,删除,查看,重命名......(简单理解 快速上手) 4875
  • 【Linux杂货铺】操作系统 3554
  • 蓝桥杯备赛 week 1 —— 递归 、递归、枚举算法(C/C++,零基础,配图) 3238
  • 进制之间的转换——n进制转换为m进制(C/C++实现,简单易懂) 3067
  • 【Linux杂货铺】文件系统 3018

分类专栏

  • C++杂货铺 25篇
  • 数据结构 9篇
  • Linux杂货铺 15篇
  • 算法杂货铺 3篇
  • 蓝桥杯备赛指南 9篇
  • LeetCode 刷题总结 11篇
  • C语言语法详解 10篇

最新评论

  • 【C++杂货铺】二叉搜索树

    一码归—码: 文章思路清晰明了,干货满满当当,感觉到博主的用心了博主很有耐心,更有对知识的热忱和热爱,写了这么实用有效的分享,值得收藏点赞。加油加油

  • 【C++杂货铺】二叉搜索树

    林戈的IT生涯: 赞文诗(其二) --林戈的IT生涯 博主优秀博文精,持续更新有耐心, 持之以恒林戈敬,积极上进人人迎。 博文气质美如花,博主才华秀中华, 林戈三连挥一键,榜上三甲必有它。

  • 【C++杂货铺】二叉搜索树

    Aileen_0v0: 博主的文章细节很到位,兼顾实用性和可操作性,内容和细节都很到位,期待博主持续带来更多好文

  • 【C++杂货铺】二叉搜索树

    Srlua小谢: 优质好文,博主的文章细节很到位,兼顾实用性和可操作性,感谢博主的分享,文章思路清晰,图文并茂,详略得当,三连支持,期待博主持续输出好文!

  • 【C++杂货铺】二叉搜索树

    寻道码路: 文中二叉树的讲解非常到位,方便理解学习,值得一看,也希望博主抽空多多指导。

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • 【C++杂货铺】二叉搜索树
  • 【C++杂货铺】多态
  • 【C++杂货铺】继承
2024年37篇
2023年33篇

目录

目录

评论 58
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秋刀鱼的滋味@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或 充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

聚圣源原发性高血压msxml4.0下载萧破天楚雨馨最新章节免费阅读母婴用品公司起名深沪吧yy怎么直播高和王一起的名字滚石30周年给集团有限公司起名中国国际金融公司与车有关的公司起名给杨姓男宝宝起名小戏骨八仙过海鼠年李姓起名新公司起名字免费起名网取钢之炼金术师下载免费起名女孩子姓安男宝起名天上飞李承铉戚薇微信昵称八字起名给出生孩子起名字温姓起名起起个英文名字男生郑姓牛宝宝起名花谢花飞花满天保罗乔治受伤视频起名 李 女孩肖起名78年属马公司起名淀粉肠小王子日销售额涨超10倍罗斯否认插足凯特王妃婚姻让美丽中国“从细节出发”清明节放假3天调休1天男孩疑遭霸凌 家长讨说法被踢出群国产伟哥去年销售近13亿网友建议重庆地铁不准乘客携带菜筐雅江山火三名扑火人员牺牲系谣言代拍被何赛飞拿着魔杖追着打月嫂回应掌掴婴儿是在赶虫子山西高速一大巴发生事故 已致13死高中生被打伤下体休学 邯郸通报李梦为奥运任务婉拒WNBA邀请19岁小伙救下5人后溺亡 多方发声王树国3次鞠躬告别西交大师生单亲妈妈陷入热恋 14岁儿子报警315晚会后胖东来又人满为患了倪萍分享减重40斤方法王楚钦登顶三项第一今日春分两大学生合买彩票中奖一人不认账张家界的山上“长”满了韩国人?周杰伦一审败诉网易房客欠租失踪 房东直发愁男子持台球杆殴打2名女店员被抓男子被猫抓伤后确诊“猫抓病”“重生之我在北大当嫡校长”槽头肉企业被曝光前生意红火男孩8年未见母亲被告知被遗忘恒大被罚41.75亿到底怎么缴网友洛杉矶偶遇贾玲杨倩无缘巴黎奥运张立群任西安交通大学校长黑马情侣提车了西双版纳热带植物园回应蜉蝣大爆发妈妈回应孩子在校撞护栏坠楼考生莫言也上北大硕士复试名单了韩国首次吊销离岗医生执照奥巴马现身唐宁街 黑色着装引猜测沈阳一轿车冲入人行道致3死2伤阿根廷将发行1万与2万面值的纸币外国人感慨凌晨的中国很安全男子被流浪猫绊倒 投喂者赔24万手机成瘾是影响睡眠质量重要因素春分“立蛋”成功率更高?胖东来员工每周单休无小长假“开封王婆”爆火:促成四五十对专家建议不必谈骨泥色变浙江一高校内汽车冲撞行人 多人受伤许家印被限制高消费

聚圣源 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化