C++stack

目录

1.什么是stack

2.容器适配器

3.stack的使用

top

push

 pop

 

4.模拟实现stack


1.什么是stack

1. stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行 元素的插入与提取操作。(后进先出)
2. stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定 的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部(即栈顶)被压入和弹出。
3. stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下
操作:
empty:判空操作
back:获取尾部元素操作
push_back:尾部插入元素操作
pop_back:尾部删除元素操作
4. 标准容器vector、deque、list均符合这些需求,默认情况下,如果没有为stack指定特定的底层容器, 默认情况下使用deque。

2.容器适配器

容器适配器(Container Adapters)是 C++ 标准库提供的一种数据结构,它们基于现有的容器类型,提供了特定的接口和功能,以便更方便地实现某些特定的数据结构和算法。容器适配器本质上是对底层容器的封装,提供了不同的数据访问方式,使它们适用于特定的用途。 

标准库中提供了三种常用的容器适配器:

stack:栈适配器,基于底层容器提供了栈数据结构的操作,如压入(push)、弹出(pop)、查看栈顶元素等。默认底层容器是 deque,但也可以使用其他支持 back() 和 push_back() 操作的容器。


queue:队列适配器,基于底层容器提供了队列数据结构的操作,如入队(push)、出队(pop)、查看队首元素等。默认底层容器是 deque,但也可以使用其他支持 back() 和 push_back() 操作的容器。


priority_queue:优先队列适配器,基于底层容器提供了优先队列数据结构的操作,支持在插入元素时根据优先级进行排序。默认底层容器是 vector,但也可以使用其他支持随机访问和插入操作的容器。

3.stack的使用

这些是C++标准库中stack类的构造函数声明。stack是一个适配器容器,它可以使用不同的底层容器来实现栈的功能。这些构造函数声明提供了不同的方式来创建和初始化stack对象,可以根据需求选择合适的构造函数。 

stack的Construct中除了构造函数,其他什么都没有,它连拷贝构造、析构都没有。这个也跟它是容器适配器有关系,因为它的成员都是自定义类型,编译器默认生成的就够用。

stack是容器适配器以后,就开始不支持迭代器了。容器支持迭代器,容器适配器不支持迭代器。

栈随便去遍历反而是不好的,因为要保证后进先出的性质。

所以取数据得用top,想取下一个数据就得先pop。

top

reference top(); 和 const_reference top() const; 是 C++ 标准库中 std::stack 类的成员函数之一。它们用于获取栈顶元素的引用。

reference top();:返回栈顶元素的引用。如果需要修改栈顶元素,可以使用这个版本。

#include <iostream>
#include <stack>

		stack<int> m;

		m.push(42);
		m.push(15);

		// 使用 top() 获取栈顶元素
		int topElement = m.top();
		cout << "Top element: " << topElement << endl;

		// 修改栈顶元素
		m.top() = 99;
		cout << "New top element: " << m.top() << endl;

		return 0;
	

}

 

后进先出,15先出,然后修改为99,最后出99

push

是 C++ 标准库中 std::stack 类的成员函数之一。它们用于将一个新的元素压入栈中。

这两个版本的 push 函数允许你在栈顶添加新的元素。如果需要保持传入值的不变性,可以使用第一个版本;如果你想利用移动语义来避免不必要的复制,可以使用第二个版本。
#include<iostream>
#include<stack>
using namespace std;


	int main() 
	{
		stack<int> m;

		m.push(10); // 使用右值,将 10 压入栈中
		m.push(19);

		int newElement = 99;
		m.push(newElement); // 使用常量引用,将 newElement 压入栈中

		cout << "Stack size: " << m.size() << endl;

		while (!m.empty())  // 遍历不能用迭代器,容器适配器不支持迭代器
		{
			cout << m.top() << " "; // 输出栈顶元素
			m.pop(); // 弹出栈顶元素
		}

		return 0;
	}

 pop

void pop(); 是 C++ 标准库中 stack 类的成员函数之一。它用于将栈顶元素弹出(删除)。

这个函数没有返回值,它只是从栈中移除栈顶元素。在调用 pop() 函数之前,需要确保栈不为空,否则会导致未定义行为。

	int main() 
	{
		stack<int> m;

		m.push(10); // 使用右值,将 10 压入栈中
		m.push(19);
		m.push(29);

		cout << "Stack size: " << m.size() << endl;

		m.pop();

		cout << "Stack new size: " << m.size() << endl;

		return 0;
	}

4.模拟实现stack

STL(标准模板库)中的 stack 和 queue 默认使用 std::deque 作为底层容器的原因是出于性能和功能的考虑。

std::deque(双端队列)是一个双向开口的动态数组,支持在队首和队尾进行高效的插入和删除操作。它的内部实现使得在队首和队尾的操作都能达到接近常数时间复杂度,这使得 std::deque 在作为底层容器时能够提供较好的性能
 

实现代码

#pragma once

#include "string.h"
#include<iostream>
#include<stack>
#include<deque>


using namespace std;


namespace lty
{
	//适配器模式
	template<class T, class Container=deque<T>>
	class stack
	{
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}

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

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

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

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

	private:
		Container _con;
	};

	void test_stack()
	{
		stack<int, deque<int>> st;
		st.push(1);
		st.push(2);
		st.push(3);
		st.push(4);

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

测试代码

#include "string.h"


int main()
{
	lty:: test_stack();
}

结果

头文件包含:代码首先包含了头文件 <deque>,这是为了使用底层容器 std::deque。

命名空间定义:代码将 stack 类放置在了命名空间 lty下,这是为了避免命名冲突和提供代码的组织结构。

stack 类模板定义:stack 类是一个模板类,有两个模板参数:T 表示栈中存储的元素类型,Container 表示底层容器的类型,默认为 std::deque<T>。

公共成员函数

push(const T& x):将传入的元素值 x 添加到底层容器的末尾,实现了入栈操作。


pop():从底层容器的末尾删除一个元素,实现了出栈操作。


T& top() 和 const T& top() const:分别返回底层容器的末尾元素的引用(允许修改)和常量引用(只读),实现了查看栈顶元素操作。


bool empty() const:返回底层容器是否为空。


size_t size() const:返回底层容器中元素的数量。


私有成员变量 _con:这是一个模板类的私有成员变量,用于存储实际的栈元素。其类型是根据模板参数 Container 确定的,在实例化时会被替换为具体的容器类型。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

git的版本控制流程

1、git是一款版本控制工具 例如我们常用的淘宝&#xff0c;每次升级&#xff0c;版本号就会加一。那么我们怎么控制版本号呢&#xff1f; --使用git。 2、最常使用的git指令 git add . 暂存 git commit -m"***" 提交到本地 git pull 将远程仓库代码下拉到本地 git …

Python知识碎片补充【侯小啾python领航班系列(十四)】

Python知识碎片补充【侯小啾python领航班系列(十四)】 大家好,我是博主侯小啾, 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ�…

c#学习相关系列之as和is的相关用法

一、子类和父类的关系 public class Program{static void Main(string[] args){Animal animal new Dog();// Dog dog (Dog)new Animal(); 编译成功&#xff0c;运行报错Dog dog (Dog)animal;Dog dog new Dog();Animal animal dog; //等价于Animal animal new Dog();}}pub…

应用于智慧社区的AI边缘计算盒子+AI算法软硬一体化方案

据统计&#xff0c;全国大约有45W个小区&#xff0c;监控高空抛物、治理乱扔垃圾、人员管理、烟火检测、占道、人流量检测、车型检测等&#xff1b;营造社区安全等需求跟每一个参与者息息相关&#xff0c;据法院公开资料显示&#xff0c;每年有1000宗以上跟高空抛物有关的各类案…

0X04

看到一道有趣的misc题 misc签到题 打开后啥都没有&#xff0c;全选后发现每一行有空格&#xff0c;数了一行发现空格数量转ascil码后是f&#xff0c;猜测都如此&#xff0c; 后面就可以交个脚本了&#xff0c;统计之后转换成ascii from Crypto.Util.number import long_to_b…

【Linux--进程控制】

目录 一、进程等待1.1进程等待方法1.2获取子进程status 二、进程替换2.1单进程版本--最简单得程序替换2.2 进程替换得原理2.3 多进程版本--验证各种程序替换接口2.4 总结 一、进程等待 1.1进程等待方法 问题1&#xff1a;进程等待是什么&#xff1f; 通过系统调用wait/waitpi…

算法:笛卡尔平面坐标系上,若干连接点形成线,剔除距离小于阈值的点,Kotlin

算法&#xff1a;笛卡尔平面坐标系上&#xff0c;若干连接点形成线&#xff0c;剔除距离小于阈值的点&#xff0c;Kotlin const val THRESHOLD 0.6f //距离小于这个点将被剔除。data class Point(val x: Float, val y: Float)fun removeNearbyPoint(points: List<Point>…

【数电笔记】逻辑代数的基本定律、常用公式

说明&#xff1a; 笔记配套视频来源&#xff1a;B站 逻辑代数的基本定律 1. 常量间的运算 2. 逻辑变量与常量的运算 3. 与普通代数相似的定律 4. 摩根定律&#xff08;反演律&#xff09; 5. 等式证明方法例题 逻辑代数的常用公式 1. 吸收律 2. 冗余律 3. 示例应用 4. 关于异…

conda 安装指定Version的指定Build

入下图&#xff0c;我想装cudnn的7.6.5的指定Build版本cuda10.0_0 应该使用如下命令&#xff1a; mamba install cudnn7.6.5cuda10.0_0 没有mamba用conda install也可以

快手获客技巧:轻松获取高转化率的潜在客户!

**一、引言** 随着互联网的发展&#xff0c;越来越多的企业开始关注短视频平台&#xff0c;尤其是快手。作为中国最大的短视频平台之一&#xff0c;快手拥有庞大的用户群体和丰富的视频内容。通过掌握快手获客技巧&#xff0c;企业不仅可以获取更多潜在客户&#xff0c;还能提高…

Flash学习

FLASH介绍 FLASH是常用的&#xff0c;用于存储数据的半导体器件&#xff0c;它具有容量大&#xff0c;可重复擦写&#xff0c;按“扇区/块”擦除、掉电后数据可继续保存的特性。 常见的FLASH有NOR FLASH和NAND FLASH。 NOR和NAND是两种数字门电路&#xff0c;可以简单地认为F…

简述MyBatis、MyBatis-Plus、以及MyBatis-Plus的简单运用

什么是MyBatis MyBatis是一个开源的Java持久层框架&#xff0c;用于简化与关系型数据库的交互。它通过将SQL语句与Java代码进行分离&#xff0c;提供了一种优雅的方式来处理数据库操作。 MyBatis的核心思想是将SQL语句与Java方法进行映射&#xff0c;使得开发人员可以通过配置…

《ChatGPT实操应用大全》探索无限可能

&#x1f5e3;️探索ChatGPT&#xff0c;开启无限可能&#x1f680; 文末有免费送书福利&#xff01;&#xff01;&#xff01; ChatGPT是人类有史以来最伟大的发明。他能写作、绘画、翻译、看病、做菜、编程、数据分析、制作视频、解高等数学题…&#xff0c;他会的技能…

FPGA 常用代码

边沿检测 Verilog边沿检测是数字电路设计中常用的方法之一。它是一种检测输入信号边沿变化的技术&#xff0c;用于实现时序控制、数据采集和数字信号处理等功能。其基本原理是通过触发器检测输入信号的状态变化&#xff0c;并触发相应的逻辑操作。 // 边沿检测模块 // 使用两…

docker踩坑记录:docker容器创建doris容器间无法通讯问题

背景&#xff1a; 开发大数据平台&#xff0c;使用doris作为数据仓储&#xff0c;使用docker做集群部署&#xff0c;先进行开发环境搭建&#xff0c;环境为BE1;FE1&#xff0c;原来使用官方例子&#xff0c;但是官方例子是创建了一个bridge使用172.20.80.0/24通讯&#xff0c;…

WPF Mvvm模式下面如何将事件映射到ViewModel层

前言 平常用惯了Command绑定,都快忘记传统的基于事件编程模式了,但是Commond模式里面有个明显的问题,就是你无法获取到事件源的参数。很多大聪明肯定会说,这还不简单,通过自己写控件,给控件加个自定义属性不就行了,想要啥事件就写啥事件进去,完全自主可控。但是对于写…

链式栈的结构与基本操作的实现(初始化,入栈,出栈,获取元素个数,判空,清空,销毁)

目录 一.链式栈的栈顶在哪里? 二.链栈的结构: 三.链式栈的实现: 四.链式栈的总结: 一.链式栈的栈顶在哪里? 二.链栈的结构: typedef struct LSNode{int data;struct LSNode* next;}LSNode ,*PLStack; //链栈的节点.由于栈顶在第一个数据节点,所以不需要top指针 三.链式…

基于SpringBoot高校心理教育辅导设计与实现

摘 要 随着Internet技术的发展&#xff0c;心理教育辅导系统应运而生&#xff0c;心理教育辅导系统为用户提供了一个更为便利的心理测试咨询平台。所以&#xff0c;为了充分满足高校学生心理教育辅导的需求&#xff0c;特开发了本高校心理教育辅导系统。 本高校心理教育辅导系统…

Python for循环及用法详解

for-in 循环专门用于遍历范围、列表、元素和字典等可迭代对象包含的元素。 for-in 循环的语法格式如下 for 变量 in 字符串&#xff5c;范围&#xff5c;集合等&#xff1a;statements 对于上面的语法格式有以下两点说明&#xff1a; for-in 循环中的变量的值受 for-in 循环控…

gstreamer移植

参考 arm-linux交叉编译Gstreamer&#xff08;重要&#xff09;gstreamer移植qnx(四)&#xff1a;交叉编译qnx版本的gstreamer插件库&#xff08;重要&#xff09;gstreamer交叉编译关于linux&#xff1a;GStreamer上的“黑名单”是什么意思&#xff1f;gstreamer 环境变亮设置…