【C++】STL-stack_queue

news2024/11/24 7:37:49

目录

1、stack和queue的使用

1.1 最小栈

1.2 栈的弹出和压入序列

1.3 二叉树的层序遍历

2、stack和queue的模拟实现

2.1 适配器

2.2 deque

2.2.1 deque的成员变量

2.2.2 deque的迭代器

2.2.3 deque尾插元素

2.2.4 deque头插元素

2.2.5 下标访问

2.2.6 deque的不足


1、stack和queue的使用

stack的使用和queue的使用与前面的vector和list类似,并且可以通过看文档来了解,这里主要通过几道题来加深对这两个容器的理解

1.1 最小栈

这道题可以定义两个栈,一个用来存放放入的元素,一个用来储存最小值

注意:最小栈是相对当前位置而言的

不能用一个min来记录最小值,因为删除元素后min无法更新,且这道题的最小值是相对当前位置

class MinStack {
public:
    MinStack() {
        //不需要初始化,因为成员变量是自定义类型,会去调用自己的构造函数
    }
    
    void push(int val) {
        st.push(val);
        if(minst.empty() || minst.top() >= val)
            minst.push(val);
    }
    
    void pop() {
        int x = st.top();
        st.pop();
        if(x == minst.top())
            minst.pop();
    }
    
    int top() {
        return st.top();
    }
    
    int getMin() {
        return minst.top();
    }
    stack<int> st;
    stack<int> minst;
};

1.2 栈的弹出和压入序列

这道题是思路是,创建一个栈,首先将pushV中的第一个数据放入栈中,用popi来记录popV的下标,初始时popi=0,比较栈顶的数据和popV[popi]是否相同,若相同,则弹出栈顶数据,并且popi++,然后继续比较现在栈顶的数据是否与popV[popi]是否相同,直到不相同再出循环或者栈中已经没有元素了再出循环:若不相同,则继续将pushV中的数据往栈中插入。若已经把pushV中的数据全部放入栈中了,并且循环判断后栈为空,说明是可以的,否则就是不可以的

bool IsPopOrder(vector<int>& pushV, vector<int>& popV) {
        size_t popi = 0;
        stack<int> st;
        for(auto e : pushV)
        {
            st.push(e);
            // 栈顶数据与出栈序列比较
            while(!st.empty() && st.top() == popV[popi])
            {
                popi++;
                st.pop();
            }
        }
        return st.empty();
    }

1.3 二叉树的层序遍历

与之前的层序遍历类似,都是利用队列,父亲结点出队列时就把左右孩子结点带入队列中。这道题的难处是要将每一层的结点放进一个数组中,然后所有层的结点组成一个二维数组,所以要如何区分队列中的结点是那一层的呢?

此时可以借助一个levelSize,levelSize表示每一层数据的个数,入队列还是父亲结点带入左右孩子结点,出队列时,需要用levelSize控制一层一层出,当levelSize==0时,说明当前层出完了,并且此时队列中的就都是下一层的结点,所以levelSize=q.size()

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> vv;
        if(root == nullptr) return vv;
        queue<TreeNode*> q;
        q.push(root);
        int levelSize = 1;// 记录每层的数据个数
        int i = 0;
        while(!q.empty())
        {
            vector<int> v;
            while(levelSize)
            {
                TreeNode* node = q.front();
                q.pop();
                levelSize--;
                v.push_back(node->val);
                if(node->left) q.push(node->left);
                if(node->right) q.push(node->right);
            }
            vv.push_back(v);
            levelSize = q.size();
        }
        return vv;
    }
};

2、stack和queue的模拟实现

vector和list称为容器,而stack和queue称为容器适配器

2.1 适配器

通过观察stack和queue、vector和list会发现,前两者的第二个模板参数和后两者的第二个模板参数不同。前两者的是适配器,后两者的是空间配置器。空间配置器是用来让容器开启空间的,而适配器是这个容器底层是通过什么实现的

适配器 -- 转换 -- 对其他容器封装一下

所以,stack的模拟实现底层可以使用vector或者list

namespace cxf
{
	template<class T,class Container = std::vector<T>>
	class stack
	{
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}
		void pop()
		{
			_con.pop_back();
		}
		T& top()
		{
			return _con.back();
		}
		const T& top() const
		{
			return _con.back();
		}
		size_t size() const
		{
			return _con.size();
		}
		bool empty() const
		{
			return _con.empty();
		}
	private:
		Container _con;
	};
}

模板参数和函数参数的区别是,模板参数用的是尖括号,函数参数用的是圆括号,模板参数传的是类型,函数参数传的是对象,所以模板参数也是可以给缺省值的

在上面这一个栈的模板中,底层默认是用vector实现的,也可以在创建的时候传入一个其他的容器来让底层变成其他容器,如list

template<class T,class Container = std::list<T>>
class queue
{
public:
	void push(const T& x)
	{
		_con.push_back(x);
	}
	void pop()
	{
		_con.pop_front();
	}
	T& top()
	{
		return _con.front();
	}
	const T& top() const
	{
		return _con.front();
	}
	size_t size() const
	{
		return _con.size();
	}
	bool empty() const
	{
		return _con.empty();
	}
private:
	Container _con;
};

适配器模式是一种设计模式,前面的vector、list是迭代器模式,同样也是一种设计模式

适配器通过一直接口来实现另一种接口,增强了代码的可维护性。当适配器不同时,实际上底层结构已经天差地别,但是使用起来完全是一样的,也具有很强的封装性

适配器选用vector和list各有优势和劣势

vector的优势是下标访问效率低

vector的劣势是扩容、头部插入删除效率低

list的优势是按需申请释放空间任意位置插入删除效率高

list的劣势是下标访问效率低

所以STL中的stack和queue的默认适配器是deque,是vector和list的结合体

2.2 deque

deque叫做双端队列,是一个容器,类似于vector和list的结合体,既可下标访问,又可头插头删

deque底层是通过一个中控数组,也就是一个指针数组来控制一个一个的buff数组

接下来,通过部分的STL源码来大概了解一下deque的底层结构

2.2.1 deque的成员变量

deque的成员函数主要就是由两个迭代器以及一个中控数组组成的

start指向的是deque中第一个buff

finish指向的是deque中最后一个buff

2.2.2 deque的迭代器

deque的迭代器是由4个成员变量组成的

node是指向这个迭代器指向的那个buff,因为buff是数组,node指向数组,所以是二级指针

first是指向这个迭代器的node指向的那个buff数组的第一个位置

last是指向这个迭代器的node指向的那个buff数组的最后一个位置的下一个位置

cur指向当前位置,在deque的成员变量start中就是第一个元素,在deque的成员变量finish中就是最后一个元素

这里面的map是T**

begin返回的是start,end返回的是finish

迭代器++是让迭代器中的cur向后走,如果cur == last,说明当前buff走完了,则让node向后移动一位

it != end 迭代器的比较是用cur来比较的

2.2.3 deque尾插元素

若最后一个buff数组没满,则在其后面插入数据,并让finish的cur向后移动

若最后一个buff数组满了,则再开一个buff数组,并且finish后移

2.2.4 deque头插元素

若第一个buff数组是满的,则头插元素会在第一个buff前面再开一个buff数组,并且start前移一位,并且这个buff数组是从后向前添加元素的

2.2.5 下标访问

以头插元素中的图为例,假设要访问下标为4的元素,易知一个buff数组能存放8个元素,第一个buff数组中有效元素个数是2,所以用8-2=6,再用6+4=10,实际需要从第一个buff数组的第一个元素开始算,直到下标为10的元素,即2

2.2.6 deque的不足

1、deque的下标访问效率不如vector

2、deque在中间插入效率不如list

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

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

相关文章

Vite: Esbuild的使用与其插件开发

概述 作为 Vite 的双引擎之一&#xff0c;Esbuild 在很多关键的构建阶段(如 依赖预编译 、 TS 语法转译 、 代码压缩 ) 让 Vite 获得了相当优异的性能&#xff0c;是 Vite 高性能的得力助手无论是在 Vite 的配置项还是源码实现中&#xff0c;都包含了不少 Esbuild 本身的基本概…

postGreSQL关系数据库介绍

什么是postGreSQL关系数据库&#xff1f; PostgreSQL 是一个强大的、开源的对象关系型数据库管理系统&#xff08;ORDBMS&#xff09;。它基于POSTQUEL查询语言的继承&#xff0c;提供了对SQL标准的广泛支持&#xff0c;并扩展了许多高级功能&#xff0c;如事务处理、多版本并…

被年轻人整不会的1688,终于开始反击了!

“我可以买贵的&#xff0c;但我不能买贵了。”成为年轻人新晋购物哲学。 最近&#xff0c;在豆瓣、小红书等社交媒体上出现了一种独特的消费趋势。在这些平台被种草之后&#xff0c;越来越多对价格敏感、注重性价比的年轻人开始挖宝“大牌平替”。他们涌入阿里巴巴旗下以批发…

配置Nginx二级域名

一、环境 &#xff08;一&#xff09;配置 1.服务器 linux CentOS 2.反向代理 Nginx 3.开放端口 云服务器开放端口80和443 二、域名备案 &#xff08;一&#xff09;腾讯云 1.腾讯云域名备案流程 备注&#xff1a;一级域名备案后&#xff0c;二级域名可以不用再备案&a…

第一个Flask程序

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 一切准备就绪&#xff0c;现在我们开始编写第一个Flask程序&#xff0c;由于是第一个Flask程序&#xff0c;当然要从最简单的“Hello World&#xff…

Qt Object:智能即时聊天室项目

目录 1.项目介绍 2.设计思路 3.Pro文件配置 4.项目演示 5.项目开源 项目介绍 智能即时聊天室系统&#xff08;AIChatProject&#xff09;是一个高效、灵活的即时通讯解决方案。它融合了百度的开源大型语言模型——文心一言&#xff0c;通过API接口实现深度集成。系统专为聊天和…

深入理解RLHF技术

在《LLM对齐“3H原则”》这篇文章中&#xff0c;我们介绍了LLM与人类对齐的“3H”原则&#xff0c;但是这些对齐标准主要是基于人类认知进行设计的&#xff0c;具有一定的主观性。因此&#xff0c;直接通过优化目标来建模这些对齐标准较为困难。本文将介绍基于人类反馈的强化学…

JavaScript的单线程与任务队列

目录 一、JavaScript为什么设计为单线程&#xff1f; 二、任务队列 &#x1f44b;&#x1f3fb; 扩展&#xff1a;异步队列里的宏任务与微任务 一、JavaScript为什么设计为单线程&#xff1f; JavaScript语言的一大特点就是单线程&#xff0c;换言之就是同一个时间只能做一…

三元和磷酸铁锂电池有什么区别?

现在的电动车大多都会使用到锂电池&#xff0c;在常见的锂电池分为两种&#xff0c;一种是三元锂电池另外一种是磷酸铁锂电池&#xff0c;面对这两种锂电池时&#xff0c;它们到底有什么不同&#xff1f; 1、材料不同 这两种锂电池的不同之处便是材料不同&#xff0c;磷酸铁锂…

中霖教育:税务师考试通过率怎么样?

税务师考试的通过率通常在20%至30%的范围内&#xff0c;涵盖五个科目&#xff1a;《税法一》、《税法二》、《财务与会计》、《涉税服务实务》和《涉税服务相关法律》&#xff0c;成绩有效期为五年。 针对税务师备考&#xff0c;有效的学习策略至关重要。 1、熟悉各科的题型和…

柯桥商务英语培训under是“在下面”,dog是“狗”,那underdog是什么意思?

英语中有很多单词 拆开看都认识 但合在一起意思就变了 就比如这个表达&#xff1a;underdog 大家都知道&#xff1a;under是下面&#xff0c;dog是狗 那么underdog是啥意思呢&#xff1f; 在小狗下面&#xff1f; 还是活得连狗都不如&#xff1f; 当然没有那么简单 但我…

C++日期类的完整实现,以及this指针的const修饰等的介绍

文章目录 前言一、日期类的实现二、this指针的const修饰总结 前言 C日期类的完整实现&#xff0c;以及this指针的const修饰等的介绍 一、日期类的实现 // Date.h #pragma once#include <iostream> using namespace std;#include <assert.h>class Date {// 友元函…

利用Python控制终端打印字体的颜色和格式

利用Python控制终端打印字体的颜色和格式—操作详解&#xff08;ANSI转义序列&#xff09; 一、问题描述二、ANSI转义序列三、具体代码和显示效果&#xff08;看懂这段代码&#xff0c;以后可随心控制字体的打印格式&#xff09; 欢迎学习交流&#xff01; 邮箱&#xff1a; z……

ONLYOFFICE 桌面编辑器 8.1 版发布:全面提升文档处理效率的新体验

文章目录 什么是ONLYOFFICE &#xff1f;ONLYOFFICE 桌面编辑器 8.1 发布&#xff1a;新功能和改进功能强大的 PDF 编辑器幻灯片版式功能从右至左语言支持多媒体功能增强无缝切换工作模式其他改进和优化总结 什么是ONLYOFFICE &#xff1f; https://www.onlyoffice.com/zh/off…

光伏发电项目是如何提高开发效率的?

随着全球对可再生能源需求的持续增长&#xff0c;光伏发电项目的高效开发成为关键。本文将深入探讨如何在实际操作中提高光伏发电项目的开发效率。 一、优化选址流程 1、数据收集与分析&#xff1a;利用卫星地图和遥感技术&#xff0c;收集目标区域的光照资源、地形地貌、阴影…

【图像分类】Yolov8 完整教程 |分类 |计算机视觉

目标&#xff1a;用YOLOV8进行图像分类。 图像分类器。 学习资源&#xff1a;https://www.youtube.com/watch?vZ-65nqxUdl4 努力的小巴掌 记录计算机视觉学习道路上的所思所得。 1、文件结构化 划分数据集&#xff1a;train,val,test 知道怎么划分数据集很重要。 文件夹…

OSI七层模型TCP/IP四层面试高频考点

OSI七层模型&TCP/IP四层&面试高频考点 1 OSI七层模型 1. 物理层&#xff1a;透明地传输比特流 在物理媒介上传输原始比特流&#xff0c;定义了连接主机的硬件设备和传输媒介的规范。它确保比特流能够在网络中准确地传输&#xff0c;例如通过以太网、光纤和无线电波等媒…

等保测评初级简答题试题

基本要求&#xff0c;在应用安全层面的访问控制要求中&#xff0c;三级系统较二级系统增加的措施有哪些&#xff1f; 答&#xff1a;三级比二级增加的要求项有&#xff1a; 应提供对重要信息资源设置敏感标记的功能&#xff1b; 应按照安全策略严格控制用户对有敏感标记重要…

MySQL高级-索引-使用规则-单列索引联合索引

文章目录 1、单列索引2、联合索引3、查看表索引4、创建 name 和 phone 索引5、查询 phone17799990010 and name韩信6、执行计划 phone17799990010 and name韩信7、创建联合唯一索引 idx_user_phone_name8、再次执行计划 phone17799990010 and name韩信9、使用了USE INDEX提示来…

为什么叫云计算?云计算的优势有哪些

说起云计算大家并不会感到陌生&#xff0c;那么为什么叫云计算&#xff1f;云计算技术的引入通常会使企业的信息技术应用更高效、更可靠、更安全。云计算支持用户在任意位置、使用各种终端获取应用服务。使用了数据多副本容错、计算节点同构可互换等措施来保障服务的高可靠性&a…