stack的使用以及模拟实现

news2024/11/23 8:45:31

🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨
🐻强烈推荐优质专栏: 🍔🍟🌯C++的世界(持续更新中)
🐻推荐专栏1: 🍔🍟🌯C语言初阶
🐻推荐专栏2: 🍔🍟🌯C语言进阶
🔑个人信条: 🌵知行合一
🍉本篇简介:>:讲解容器适配器 "栈"的使用以及模拟实现.
金句分享:
✨那些所谓的遗憾,可以也是一种成长!✨

前言

目录

  • 前言
  • 一、"栈"的介绍:
  • 二、栈的使用
    • 2.1 创建栈
    • 2.2 栈的常见使用接口
      • 🍔push()和emplace()的区别
    • 2.3 练练手
      • 🍉用栈实现队列
  • 三、模拟实现
  • 四、结语

一、"栈"的介绍:

栈是一种先进后出(Last-In-First-Out)的数据结构,类似于往箱子里面放东西,最先放进去的在最下面,只有上面的东西都被拿出来,才能取到下面的.
栈有两个基本操作:压入(push)和弹出(pop)。新元素通过压入操作被添加到栈的顶部,而位于栈顶的元素可以通过弹出操作被移除。除此之外,栈还有一个重要的操作是访问栈顶的元素,这可以通过 top() 方法实现。

  1. stack是一种容器适配器,适用于先进后出的环境中.
    何为容器适配器?就是将容器进行一定封装形成的一个只在容器一端进行元素的插入获取,以及删除操作。栈本身它是一种容器类型,但是它是基于其他容器类型的实现而创建的。

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

  3. stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下
    操作:
    empty:判断是否为空栈
    top:获取栈顶元素
    push_back:压栈
    pop_back:出栈

  4. 标准容器vectordequelist均符合这些需求,默认情况下,如果没有为stack指定特定的底层容器,
    默认情况下使用deque
    在这里插入图片描述

二、栈的使用

在这里插入图片描述

接口名解释
empty()判断是否为空栈
size()返回栈中有效元素的个数
top()返回栈顶元素的引用(方便修改)
push()将新元素压栈
emplace()将新元素压栈
pop()将栈顶元素出栈

2.1 创建栈

stack<int> s1;
stack<string> s2;
stack<double> s3;

2.2 栈的常见使用接口

示例代码:

void test1()
{
	//创建一个存储整形的栈
	stack<int> s1;

	//插入数据
	s1.push(5);
	s1.push(4);
	s1.push(3);
	s1.push(2);
	s1.push(1);
	s1.emplace(-1);

	//查看栈中有效元素的个数
	cout << "size=" << s1.size() << endl;

	修改栈顶元素
	//int& top = s1.top();
	//top = 66;

	//打印栈中的所有元素
	while (!s1.empty())
	{
		cout << s1.top() << endl;//打印栈顶元素
		s1.pop();//出栈
	}
}

运行结果:

size=6
-1
1
2
3
4
5

🍔push()和emplace()的区别

STL中,push()和emplace()都是向容器中添加一个元素,但是它们有以下不同:

1.① push()只能将一个已经创建的对象压入容器中,并且该对象的副本被创建,因此需要调用拷贝构造函数。

②而emplace()直接在容器中创建一个新对象,因此不需要调用拷贝构造函数创建副本.

  1. push()方法需要传递一个已经创建好的对象,而emplace()方法需要传递的是要创建对象的构造函数参数。

  2. push()方法适用于已经存在的对象,而emplace()方法适用于构造一个新对象。

从上面来看emplace()方法更高效,因为它直接在容器中创建一个新对象,而不是创建一个临时对象并将其复制到容器中。因此,在需要创建大量对象的情况下,emplace()方法比push()方法更适合。

class People
{
	friend ostream& operator<<(ostream& _cout, const People& p1);
public:
	People(string name, int age = 18)
		:_name(name)
		,_age(age)
	{
		cout << "People的构造:" << endl;;
	}
	
	People(const People& p1)
		:_name (p1._name)
		,_age(p1._age)
	{
		cout << "People的拷贝构造:" << endl;
	}

private:
	string _name;
	int _age;
};
ostream& operator<<(ostream& _cout,const People& p1)
{
	_cout << p1._name;
	_cout << " :";
	_cout << p1._age;
	return _cout;
}
void test1()
{
	stack<People> s1;
	People p1("张三");
	s1.push(p1);
	//s1.push("王五",22);//报错
	s1.emplace("李四",20);
	while(!s1.empty())
	{
		cout << s1.top() << endl;
		s1.pop();
	}
}
int main()
{
	test1();
	return 0;
}

People的构造:
People的拷贝构造:
People的构造:
李四 :20
张三 :18

首先:
push不能像emplace("李四",20);这样直接传参构造对象.
其次:
push还会调用拷贝构造函数,将对象的副本压栈.

2.3 练练手

🍉用栈实现队列

还记得我们c语言阶段实现的这个题目吗?

用栈实现队列博文(C语言版本)

题目链接:传送门

由于C语言中并没有STL库,需要手撕栈.
当时写了一百多行代码,才完成这道题.
在这里插入图片描述

如今,C++不仅不用手动造轮子,还会自动调用析构和构造函数.
试着练练手吧!

参考代码:

class MyQueue {
public:
	MyQueue() {}
	void push(int x) {
		push_stack.push(x);
	}
	int pop() {
		int ret = peek();//保存队首元素
		pop_stack.pop();//出队列
		return ret;
	}
	int peek() {//返回队首元素
		if (pop_stack.empty()){
			//倒数据
			while (!push_stack.empty()){
				pop_stack.push(push_stack.top());
				push_stack.pop();
			}
		}
		int ret = pop_stack.top();
		return ret;
	}
	bool empty() {
		return push_stack.empty() && pop_stack.empty();
	}
private:
	stack<int> push_stack;
	stack<int> pop_stack;
};

三、模拟实现

其实stack的模拟实现极其简单.
这里底层复用vector的接口即可.

在这里插入图片描述

#include <iostream>
#include <vector>
#include <stack>
using namespace std;

namespace cjn
{
	template<class 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:
		std::vector<T> _c;//底层采用vector的接口实现
	};
}

四、结语

的应用也是十分广泛的,后续的二叉树,表达式求值都利用了栈的后进先出的特性.

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

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

相关文章

活动预告|Dragonfly 与你相约 2023 KubeCon Shanghai!

KubeCon CloudNativeCon Open Source Summit China 2023&#xff0c;由 Linux 基金会、CNCF 主办&#xff0c;将在 9 月 26-28 日于上海跨国采购会展中心盛大开幕。本次峰会将聚集全球社区&#xff0c;共同探讨云原生和开源领域的前沿洞察、核心技术与最佳实践&#xff0c;会…

Java基于SpringBoot的藏区特产销售系统的研究与实现

今天为大家带来的是基于 Java SpringBootVue 的藏区特产销售系统&#xff0c;大家有兴趣的可以看一下 博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W,Csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 文章目…

ruoyi(若依)接口拦截路径配置,接口访问要授权,放开授权直接访问

1.找到文件SecurityConfig.java文件&#xff0c;里面配置相应的放行路径

[计算机入门] Windows附件程序介绍(办公类)

3.13 Windows附件程序介绍(办公类) 3.13.1 写字板 Windows系统中的写字板程序是一款简单而实用的文本编辑工具&#xff0c;它被广泛应用于快速记录笔记、绘制草图和进行简单的文档编辑。以下是写字板程序的主要功能和作用&#xff1a; 文本输入和编辑&#xff1a;写字板程序允…

数据结构-----二叉树的创建和遍历

目录 前言 二叉树的链式存储结构 二叉树的遍历 1.前序遍历 2.中序遍历 3.后序遍历 二叉树的创建 创建一个新节点的函数接口 1.创建二叉树返回根节点 2.已有根节点&#xff0c;创建二叉树 3.已有数据&#xff0c;创建二叉树 前言 在此之前我们学习了二叉树的定义和储…

HTML5+CSS3小实例:脉冲波纹催眠动画特效

实例:脉冲波纹催眠动画特效 技术栈:HTML+CSS 效果: 源码: 【html】 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content=&qu…

ThingsBoard 前端项目背景图片部件开发

前言 ThingsBoard 是目前 Github 上最流行的开源物联网平台&#xff08;14.4k Star&#xff09;&#xff0c;可以实现物联网项目的快速开发、管理和扩展, 是中小微企业物联网平台的不二之选。 本文介绍如何在 ThingsBoard 前端项目中开发背景图片部件。 产品需求 最近接到产…

掌握可扩展和可维护应用程序:12-Factor应用程序开发的全面指南

1*vhxOhTuKSyuuAKu-nUQ5SA.jpeg 在今天的快节奏世界中&#xff0c;软件开发人员需要创建可扩展、可维护和适应性强的应用程序。12-Factor应用程序方法论是一组最佳实践&#xff0c;可以帮助开发人员实现这些目标。 本文深入探讨了12个因素&#xff0c;详细解释了它们的重要性以…

python 深度学习 解决遇到的报错问题5

目录 一、conda安装shapefile失败 二、conda安装osmnx失败&#xff1a;To search for alternate channels that may provide the conda package yourelooking for, navigate to 三、ERROR: Could not build wheels for llvmlite, which is required to install pyproject.to…

算法基础--位运算

一、常见位运算总结&#xff1a; 1、基础位运算&#xff08;^&#xff09; 其中异或^有2种理解。 2、位图bitset相关&#xff08;&|&#xff09; test判断第x位是1函数0: 可以让n右移&#xff0c;也可以让1左移&#xff0c;习惯上选择第一种 (n>>x)&1 判…

初创企业应该选一款怎样的客服系统?

互联网经济时代的飞速发展&#xff0c;促使客户市场对于企业服务的要求越来越高。客户在选择产品的时候已经不单单却决于产品功能和价格&#xff0c;客户服务也是其关注的重点。 优质的客户服务所带来的是客户满意度的提升&#xff0c;以及品牌影响力的提高。所以&#xff0c;…

Linux 服务器下 pypy 下载数据集

Linux 服务器下 pypy 下载数据集 安装 pip install bypy链接自己的百度网盘 命令行直接输入 byby info 就行 byby info查看网盘里面的内容 bypy listbyby list 只显示自动生成的bypy中的文件&#xff0c;上传也是在这个目录中&#xff0c;可以自己在里面新建文件夹 4. 上传…

tsar-性能监控工具

简介 tsar是淘宝自己开发的一个采集工具&#xff0c;主要用来收集服务器的系统信息&#xff08;如cpu&#xff0c;io&#xff0c;mem&#xff0c;tcp等&#xff09;&#xff0c;以及应用数据&#xff08;如squid haproxy nginx等&#xff09;。收集到的数据存储在磁盘上&#…

SMOKE-CMAQ实践技术应用

大气污染物排放是空气污染的源头&#xff0c;气象因素是影响污染程度的重要因素&#xff0c;因此空气质量模式要求气象资料和污染物排放清单作为输入&#xff0c;其中由于大气污染源复杂性、数据滞后性、动态变化、规律性不明显等特点&#xff0c;使得大气污染源排放清单输入准…

【牛客网】OR63 删除公共字符串

思路 创建哈希表,将第二个字符串中出现过的字符添加到哈希表中创建StringBuffer来拼接最后的结果字符串遍历字符串一,如果字符在哈希表中出现过,就不拼接到字符串中,反之则拼接 Java代码 import java.util.*;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public cl…

ISIS的高级特性

1、IS-IS邻接关系建立原则 L1的路由器只能和L1的路由器建立邻接关系&#xff0c;也可以和L1、2的路由建立邻接关系 L2的路由器只能和L2的路由器建立邻接关系&#xff0c;也可以和L1、2的路由建立邻接关系 DIS只有在广播型网络中才会选举 LSP相当于OSPF中的LSA IS-IS链路状态报文…

JUC第十讲:CAS,Unsafe和原子类详解

JUC第十讲&#xff1a;CAS,Unsafe和原子类详解 JUC中多数类是通过volatile和CAS来实现的&#xff0c;CAS本质上提供的是一种无锁方案&#xff0c;而Synchronized和Lock是互斥锁方案; java原子类本质上使用的是CAS&#xff0c;而CAS底层是通过Unsafe类实现的。本文是JUC第十讲&a…

广东海颐开发笔试编程题回顾

题目一 1、现以序列{22, 24, 30, 14, 10, 17, 15, 20, 16, 23}的顺序进行输入&#xff0c;请画出构造出的平衡二叉树?请写出实现二叉树左旋的代码?&#xff08;具体题目忘记了&#xff0c;就随机搞个排序&#xff0c;思路和方法都是一样的&#xff09; 图 顺序 {22, 14, 10…

【C++】多态,从使用到底层。

文章目录 前言一、多态的概念二、多太的定义和实现2.1 多太的构造条件2.2 虚函数2.3 重写(覆盖)2.4 C11 override 和 final2.5 重载&#xff0c;隐藏&#xff0c;重写 三、多态的原理3. 1虚函数表3.2 虚函数表如何完成多态的功能3.3 虚函数表存储在内存空间的那个区域&#xff…

服务断路器_Resilience4j超时降级

创建模块cloud-consumer-resilience4j-order80 POM引入依赖 <dependencies><!-- 引入Eureka 客户端依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</a…