【c++】【STL】stack类、queue类、deque类详解及模拟

news/2024/6/3 17:30:09 标签: kubernetes, 容器, 云原生, c++, 开发语言, list, 数据结构

🪐🪐🪐欢迎来到程序员餐厅💫💫💫

         今日主菜:stack和queue,deque类

                 主厨:邪王真眼

            所属专栏:c++专栏

              主厨的主页:Chef‘s blog

这可是我和c++之间让人热血沸腾的组合技啊!


[本节目标]

  • 1.容器适配器

  • 2. stack的介绍和模拟

  • 3. queue的介绍和模拟

  • 4.deque的介绍

1. 容器适配器

适配器是一种设计模式 ( 设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结) 该种模式是将一个类的接口转换成客户希望的另外一个接口
虽然 stack queue 中也可以存放元素, 但在STL中并没有将其划分在容器的行列 ,而是将其称为 容器适配器 ,这是因为 stack 和队列只是对其他容器的接口进行了包装,

2. stack的介绍和模拟

2.1 stack的介绍

1. stack是一种容器适配器,专门用在具有后进先出(FILO)操作的环境中,其删除只能从容器的一端进行元素的插入与提取操作。

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

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

  • empty:判空操作
  • back:获取尾部元素操作
  • push_back:尾部插入元素操作
  • pop_back:尾部删除元素操作

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

我们先用vector来模拟一下

2.2 成员变量

注意事项:

         我们用的是模板,第一个参数表示数据类型,第二个表示stack是对哪个容器的封装

template<class T, class container = vector<T >>
class stack
{
public:
	//函数
private:
	container _con;
};

2.3 构造函数:

这个不用写,因为自动生成的默认构造函数会去调用container对应的容器的默认构造,这里就是vectro的默认构造。

2.4empty

是否为空栈

bool empty()
{
	return _con.empty;
}

2.5size

栈中的元素个数

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

2.6top

获取栈顶元素,注意返回值是传引用

	const T& top()const
	{
		return _con.back();
	}
	 T& top()
	{
		return _con.back();
	}

2.7push

将某个元素入栈

void push(T& val)
{
	_con.push_back(val);
}

2.8pop

将栈顶弹出

	void pop()
	{
		_con.pop_back();
	}

三:queue的介绍和模拟

3.1 queue的介绍

1. 队列是一种容器适配器,专门用于在 FIFO(先进先出) 中操作,其中从容器一端插入元素,另一端提取元素。
2. 队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类, queue 提供一组特定的成员函数来访问其元素。元素从队尾入队列,从队头出队列。
3. 底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操作:
  • empty:检测队列是否为空
  • size:返回队列中有效元素的个数
  • front:返回队头元素的引用
  • back:返回队尾元素的引用
  • push_back:在队列尾部入队列
  • pop_front:在队列头部出队列
4. 标准容器 deque list 满足了这些要求。默认情况下,如果没有为 queue 实例化指定容器类,则使用标准容器deque

 

我们先用vector来模拟一下

 

 3.2成员变量

template<class T, class container = vector<T>>
class queue
{
public:
	// 函数
private:
	container _con
};

3.3 构造函数:

这个不用写,因为自动生成的默认构造函数会去调用container对应的容器的默认构造,这里就是vectro的默认构造。

3.4empty

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

3.5size

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

3.6front

const T& front()const
{
	return _con.front();
}
 T& front()
{
	return _con.front();
}

3.7back

两个重载就不用我多说了吧

const T& back()const
{
	return _con.back();
}
 T& back()
{
	return _con.back();
}

3.8push

void push(T& val)
{
	_con.push_back(val);
}

3.9pop

void pop()
{
	_con.pop_front();
}

四:deque的介绍

4.1 deque的原理介绍

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

4.2 deque的底层结构

deque 并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际 deque 类似于一个动态的二维 数组 ,其底层结构如下图所示:
一开始在中间开辟空间,随后根据需求向两边进行扩容

4.3deque的迭代器

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

4.4deque的缺陷与优势

优势:

  • vector比较deque的优势是:头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不需要搬移大量的元素,因此其效率是必vector高的。
  • list比较,其底层是连续空间,空间利用率比较高,不需要存储额外字段。

劣势:

  • 但是,deque有一个致命缺陷:不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到某段小空间的边界,导致效率低下
  • 中间元素插入删除时间复杂度高

简单来说,他的规避了vector和list的劣势,他的劣势是没有vector和list那么极端的优势(如vector的随机访问,list的插入删除)。

4.45为什么选择deque作为stackqueue的底层默认容器

stack 是一种后进先出的特殊线性数据结构,因此只要具有 push_back() pop_back() 操作的线性结构,都可以作为stack 的底层容器,比如 vector list 都可以; queue 是先进先出的特殊线性数据结构,只要具有push_back和 pop_front 操作的线性结构,都可以作为 queue 的底层容器,比如 list 。但是 STL 中对 stack 和queue默认选择 deque 作为其底层容器,主要是因为:
  • 1. stackqueue不需要遍历(因此stackqueue没有迭代器),只需要在固定的一端或者两端进行操作。
  • 2. stack中元素增长时,dequevector的效率高(扩容时不需要搬移大量数据)queue中的元素增长时,deque不仅效率高,而且内存使用率高。
结合了deque的优点,而完美的避开了其缺陷。

 总结:

这节课我们学了容器适配器vector、list类的模拟、deque的底层设计,看到了他迭代器的复杂应用

觉得有用的话就点个赞支持一下吧 😘😘😘


http://www.niftyadmin.cn/n/5451338.html

相关文章

⨯ EPERM: operation not permitted, link ...

新增区块链相关包后&#xff0c;项目在部署的时候报错&#xff0c;报错内容如下&#xff1a; 报错信息&#xff1a; ⨯ EPERM: operation not permitted, link /Users/XXX/.cache/act/be662ca67b3f7553/hostexecutor/node_modules/bigint-buffer/build/node_gyp_bins/python…

什么是DDOS肉鸡?如何防范你的服务器云主机成为“肉鸡”?

DDoS攻击近年虽然有减少趋势&#xff0c;但是高竞争行业依然是主要目标客户。一旦游戏服务器受到攻击&#xff0c;轻则是玩家掉线&#xff0c;重则是金钱损失。不管对玩家还是自身业务来说&#xff0c;这影响都是非常大。 终究原因&#xff0c;一方面是不法分子的问题&#xff…

迷宫(一)(DFS BFS)

//新生训练 #include <bits/stdc.h> using namespace std; int n, m; bool f; char mp[15][15]; int vis[15][15]; int dir[4][2] {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; bool in(int x, int y) {return 0 < x && x < n && 0 < y && y …

ubuntu 22.04 LTS 内核从 5.15.0 升级到 6.6.0

ubuntu 22.04LTS 内核从 5.15.0 升级到 6.6.0 ubuntu 22.04LTS 内核从 5.15.0 升级到 6.6.0升级内核时报错解决方法 内核升级过程回滚到先前版本 ubuntu 22.04LTS 内核从 5.15.0 升级到 6.6.0 升级内核时报错 ubuntu22.04LTS源码编译升级内核时报错&#xff0c; make[3]: **…

【分布式】——降级熔断限流

降级&熔断&限流 ⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记仓库&#x1f449;https://github.com/A-BigTree/tree-learning-notes 个人主页&#x1f449;https://www.abigtree.top ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点…

鬼探头电动车要抓要罚!两条腿走路,足球是你的哇必备技能,也可以是我们的下个机会!——早读(逆天打工人爬取热门微信文章解读)

安全驾驶&#xff0c;人人有责&#xff0c;特别是电动车&#xff01; 引言Python 代码第一篇 人民日报 生死关头在断桥拦车的五人&#xff0c;获奖金34000元&#xff01;第二篇 人民日报 来啦 早班新闻要闻社会政策 结尾 驾驶途中 车轮滚滚承载生命之重 每一瞬专注皆是对命运的…

❤ leetCode简易题1-两数之和、简易2--回文数判断、简易14-最长公共前缀

❤ leetCode简易题1-两数之和、简易题14- 最长公共前缀 1、简易1-两数之和 ① 题目要求 数字A B target&#xff0c;以target为求和结果&#xff0c;找出数组中符合的A、B数字下标。 第一次做的时候完全脑子一片蒙&#xff0c;随后认真看了看题目发现是发现找符合target和…

教程2_图像的合并及融合

1、图像加法 您可以通过OpenCV函数 cv.add() 或仅通过 numpy 操作 res img1 img2 添加两个图像。两个图像应具有相同的深度和类型&#xff0c;或者第二个图像可以只是一个标量值。 注意: OpenCV加法和Numpy加法之间有区别。OpenCV加法是饱和运算&#xff0c;而Numpy加法是模运…