栈Stack和队列Queue
目录
一、栈
(1)用数组实现
(2)用单链表实现
(3)用标注尾结点的单链表实现
(4)用双向链表实现
2、栈的实际应用
(1)改变元素的序列
(2)将递归转化为循环(逆序打印链表)
(3)括号匹配
(4)逆波兰表达式求值
(5)出栈入栈次序匹配
(6)最小栈
二、队列
1、队列的使用
2、队列的模拟实现
3、循环队列
4、双端队列Deque
三、面试题
1、用栈实现队列
2、用队列实现栈
一、栈
栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作
进行数据插入和删除操作的一端称为栈顶,另一端称为栈底
栈中的数据元素遵守后进先出的原则
- 压栈/进栈/入栈:栈的插入操作
- 出栈:栈的删除操作
方法 | 功能 |
Stack() | 构造一个空的栈 |
E push(E e) | 将e入栈,并返回e |
E pop() | 将栈顶元素出栈并返回 |
E peek() | 获取栈顶元素 |
int size() | 获取栈中有效元素个数 |
boolean empty() | 检测栈是否为空 |
1、栈的模拟实现
(1)用数组实现
(2)用单链表实现
- 若使用尾插法,则入栈时间复杂度为O(n),出栈时间复杂度为O(n)
- 若使用头插法,则入栈复杂度为O(1),出栈复杂度为O(1)
(3)用标注尾结点的单链表实现
- 尾插法:入栈O(1),出栈O(n)(因为删除尾结点依旧要遍历到前一个结点,改变其next值)
- 头插法:入栈O(1),出栈O(1)
(4)用双向链表实现
无论尾插还是头插时间复杂度都为O(1)
LinkedList<Integer> stack=new LinkedList<>();stack.push(1);// addFirst(e);stack.push(2);stack.push(3);System.out.println(stack.peek());//拿到头结点3
2、栈的实际应用
(1)改变元素的序列
(2)将递归转化为循环(逆序打印链表)
//1、递归方式void reverseprintList1(Node head){if(head!=null){printList(head.next);System.out.print(head.val + " ");}}
//2、循环方式void reverseprintList2(Node head){if(head==null){return;}Stack<Node> s = new Stack<>();// 将链表中的结点保存在栈中Node cur = head;while(cur!=null){s.push(cur);cur = cur.next;}// 将栈中的元素出栈while(!s.empty()){System.out.print(s.pop().val + " ");}}
(3)括号匹配
给定一个只包含' ( '、' ) '、' { '、' } '、' [ '、' ] '的字符串s,判断括号是否匹配。匹配条件:左括号必须与相同类型的右括号闭合,不可交错排列
匹配示例:(){}[]、({}[])、([{}])、()[{}]
public boolean isValid(String s) {Stack<Character> stack=new Stack<Character>();for (int i = 0; i < s.length(); i++) {char c=s.charAt(i);if (c=='(' || c=='[' || c=='{'){//c为左括号就添加进来等着对称匹配stack.push(c);}else {//c为右括号//此时栈中可能有左括号等着匹配,也可能为空(无法匹配)if (stack.empty()){return false;}//不为空,则栈中存放的是左括号,那就判断c与栈顶元素是否匹配(因为两括号必须要对称匹配)char top=stack.peek();if (c==')' && top=='(' || c==']' && top=='[' || c=='}' && top=='{'){//对称匹配了则弹出此左括号stack.pop();}else {//遇到一个右括号无法与栈顶左括号对称匹配,则无法匹配return false;}}}//如果s遍历完发现栈中不为空,即栈中仍有残存左括号未进行匹配,不匹配if (!stack.empty()){return false;}//否则匹配return true;}
(4)逆波兰表达式求值
中缀表达式转化为后缀表达式技巧:
public int evalRPN(String[] tokens) {Stack<Integer> stack=new Stack<>();for (String s : tokens) {if (!isOperation(s)) {//压入数字字符stack.push(Integer.parseInt(s));}else {//运算符则弹出栈顶2个元素进行操作(先弹出的放运算符右边)int num2=stack.pop();int num1=stack.pop();switch (s){case "+":stack.push(num1+num2);break;case "-":stack.push(num1-num2);break;case "*":stack.push(num1*num2);break;case "/":stack.push(num1/num2);break;}}}return stack.pop();}private boolean isOperation(String s) {if (s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/")){//是运算符return true;}return false;}
(5)出栈入栈次序匹配
public boolean IsPopOrder (int[] pushV, int[] popV) {Stack<Integer> stack=new Stack<>();int j=0;for (int i = 0; i < pushV.length; i++) {stack.push(pushV[i]);while (!stack.empty() && j<popV.length && stack.peek()==popV[j]){stack.pop();j++;}}return stack.empty();}
(6)最小栈
class MinStack {private Stack<Integer> stack;private Stack<Integer> minStack;//存储阶段性最小值private int minValue;public MinStack() {stack=new Stack<>();minStack=new Stack<>();}public void push(int val) {stack.push(val);if (minStack.empty()){minStack.push(val);}else {if (val<=minStack.peek()){minStack.push(val);}}}public void pop() {if (!stack.empty()){int ret=stack.pop();if (minStack.peek()==ret){minStack.pop();}}}public int top() {//获取stack栈顶元素if (stack.empty()){return -1;}return stack.peek();}public int getMin() {//获取minStack栈顶元素if (minStack.empty()){return -1;}return minStack.peek();}
}
- 栈:一种数据结构。是一种特殊的线性表,只允许在栈顶进行插入和删除操作,栈顶的数据元素遵守后进先出的原则
- 虚拟机栈:JVM内存管理的一部分,用于管理函数调用的内存和回收。属于线程私有,确保每个线程的内存隔离和安全。
- 栈帧:函数调用过程中的内存管理单元。包含局部变量表、操作栈等信息。每个方法在运行时JVM都会创建一个栈帧,并将其压入虚拟机栈中;当方法调用结束时对应的栈帧会从虚拟机栈中出栈,确保函数调用的顺利进行和结束后的资源释放
二、队列
队列:只允许在一端进行插入和删除数据操作,在另一端进行删除数据操作的特殊线性表
- 进行插入操作的一端称为队尾,进行删除操作的一端称为队头
- 队列遵守先进先出的原则
1、队列的使用
在Java中,Queue是个接口,底层是通过链表实现的
方法 | 功能 |
boolean offer(E e) | 入队列 |
E poll() | 出队列 |
peek() | 获取队头元素 |
int size() | 获取队列中有效元素个数 |
boolean isEmpty() | 检测队列是否为空 |
Queue是个接口,在实例化时必须实例化LInkedList的对象,因为LinkedList实现了Queue接口
Queue<Integer> q = new LinkedList<>();// 从队尾入队列q.offer(1);q.offer(2);q.offer(3);q.offer(4);q.offer(5);System.out.println(q.size());//5System.out.println(q.peek()); // 获取队头元素 1q.poll();//弹出队头元素 1System.out.println(q.poll()); // 从队头出队列,并将删除的元素返回 2if(q.isEmpty()){System.out.println("队列空");}else{System.out.println(q.size());//3}
2、队列的模拟实现
队列中既然可以存储元素,那底层肯定要有能够保存元素的空间。通过前面线性表的学习了解到常见的空间类型有2种:顺序结构和链式结构。那是用哪种结构实现比较好呢?
(1)双向链表实现
(2)数组实现
如果rear==elem.length-1之后发现数组前面还有位置还可以往前面插入元素就好了,这时候也就是我们的循环队列
3、循环队列
数组设计循环队列
4、双端队列Deque
双端队列是指允许两端都可以进行入队和出队操作的队列
Deque是一个接口,使用时必须创建LinkedList对象
在实际工程中,使用Deque接口是比较多的,栈和队列均可以使用该接口
Deque<Integer>stack =newArrayDeque<>();//双端队列的线性实现
Deque<Integer>queue=newLinkedList<>();//双端队列的链式实现
三、面试题
1、用栈实现队列
class MyQueue {Stack<Integer> inStack;Stack<Integer> outStack;public MyQueue() {inStack=new Stack<>();outStack=new Stack<>();}public void push(int x) {inStack.push(x);}public int pop() {if (empty()){return -1;//队列此时为空}if (outStack.empty()){while (!inStack.empty()){outStack.push(inStack.pop());}}return outStack.pop();}public int peek() {if (empty()){return -1;}if (outStack.empty()){while (!inStack.empty()){outStack.push(inStack.pop());}}return outStack.peek();}public boolean empty() {return inStack.empty() && outStack.empty();}
}
2、用队列实现栈
class MyStack {private Queue<Integer> qu1;private Queue<Integer> qu2;public MyStack() {qu1=new LinkedList<>();qu2=new LinkedList<>();}//入栈入到不为空的队列,都为空则入到qu1即可public void push(int x) {if (!qu1.isEmpty()){qu1.offer(x);}else if (!qu2.isEmpty()){qu2.offer(x);}else {qu1.offer(x);}}//出栈出不为空的队列size-1个。最后一个元素就是要出栈的元素public int pop() {if (empty()){return -1;//栈为空}if (!qu1.isEmpty()){int size=qu1.size();for (int i = 0; i < size - 1; i++) {qu2.offer(qu1.poll());}return qu1.poll();}else {int size=qu2.size();for (int i = 0; i < size - 1; i++) {qu1.offer(qu2.poll());}return qu2.poll();}}public int top() {int tmp=-1;if (empty()){return -1;//栈为空}if (!qu1.isEmpty()){int size=qu1.size();for (int i = 0; i < size; i++) {tmp=qu1.poll();qu2.offer(tmp);//出的最后一个元素存在tmp即为栈顶元素}return tmp;}else {int size=qu2.size();for (int i = 0; i < size; i++) {tmp=qu2.poll();qu1.offer(tmp);}return tmp;}}public boolean empty() {return qu2.isEmpty() && qu1.isEmpty();}
}
相关文章:
栈Stack和队列Queue
目录 一、栈 (1)用数组实现 (2)用单链表实现 (3)用标注尾结点的单链表实现 (4)用双向链表实现 2、栈的实际应用 (1)改变元素的序列 (2&am…...
uniapp 微信小程序地图标记点、聚合点/根据缩放重合点,根据缩放登记显示气泡marik标点
如图,如果要实现上方的效果: 上方两个效果根据经纬度标记点缩放后有重复点会添加数量 用到的文档地址https://developers.weixin.qq.com/miniprogram/dev/api/media/map/MapContext.addMarkers.htmlMapContext.addMarkers(Object object) 添加标记点Ma…...
Percona XtraBackup备份docker版本mysql 5.7
my.cnf配置文件 [client] default_character_setutf8[mysqld] # 数据存储目录(必须手动指定) datadir/var/lib/mysql/data# 字符集 collation_server utf8_general_ci character_set_server utf8 # 二进制日志 server-id1 log_bin/var/log/mysql/binl…...
C++:关联式容器的介绍及map与set的使用
我们之前已经学习过string,vector,list,queue,priority_queue等容器,这些容器我们统称为序列式容器,因为它们的数据的逻辑结构呈线性。因为这些容器中存储的数据即便二者之间发生交换,也不会对原有的容器结构造成太大影响。 但上篇文章我们介…...
一文说清:Linux下C++静态库的封装和调用
一 引言 《一文说清:windows下C静态库的封装和调用》中说了: 静态库允许开发者在多个项目中复用代码,减少重复劳动,并增强程序的可维护性。并讲述了windows环境下创建、封装以及调用C静态库的过程。 本文则描述了,如…...
【Java 学习】数据类型、变量、运算符、条件控制语句
Java基础语法 1. 打印 Hello World !2. 变量类和数据类型2.1 什么是变量?什么是数据类型?2.2 常用的数据类型2.3 使用变量2.4 String 类数据类型2.4.1 String 类基本概念2.4.2 String 类的使用 3. 运算符3.1 算数运算符3.2 关系运算符3.3 逻辑运算符3.4 …...
【软考】系统架构设计师-数据库设计基础
数据库核心考点 三级模式-两级映射 外模式--视图 概念模式--表(模式、基本表) 内模式--物理文件 数据库设计 概念结构设计:属性冲突、命名冲突、结构冲突 逻辑结构设计:关系模式(层次模型、网络模型)…...
【Jmeter相关】
Jmeter 可以作为接口测试问题,也会涉及到性能相关的问题 一、JMeter中用户定义的变量(User Defined Variables)和用户参 数(User Parameters)的区别是什么? 在JMeter中都是用于定义和存储测试数据的方法,但它们有一…...
拍立淘按图搜索API接口系列,返回示例图参考
拍立淘按图搜索API接口允许用户通过上传图片来搜索相似的商品,该接口返回的通常是一个JSON格式的响应,其中包含了与上传图片相似的商品信息。以下是一个基于淘宝平台的拍立淘按图搜索API接口返回数据的JSON格式示例,同时提供对其关键字段的解…...
OSG开发笔记(三十二):深入理解相机视口、制作支持与主视图同步变换旋转的相机HUD
若该文为原创文章,未经允许不得转载 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/143852695 各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究 长沙红胖子Qt…...
2024RISC-V中国峰会 演讲幻灯片和视频回放均已公开
目录 一、幻灯片地址: 二、演讲视频: 一、幻灯片地址: RVSC2024/slides at main cnrv/RVSC2024 GitHub 二、演讲视频: RISC-V国际基金会的个人空间-RISC-V国际基金会个人主页-哔哩哔哩视频...
河道无人机雷达测流监测系统由哪几部分组成?
在现代水利管理中,河道无人机雷达监测系统正逐渐成为一种重要的工具,为河道的安全和管理提供了强大的技术支持。那么,这个先进的监测系统究竟由哪几部分组成呢? 河道无人机雷达监测系统工作原理 雷达传感器通过发射电磁波或激光束…...
28.<Spring博客系统⑤(部署的整个过程(CentOS))>
引入依赖 Spring-boot-maven-plugin 用maven进行打包的时候必须用到这个插件。看看自己pom.xml中有没有这个插件 并且看看配置正确不正常。 注:我们这个项目打的jar包在30MB左右。 <plugin><groupId>org.springframework.boot</groupId><artif…...
OpenAI震撼发布:桌面版ChatGPT,Windows macOS双平台AI编程体验!
【雪球导读】 「OpenAI推出ChatGPT桌面端」 OpenAI重磅推出ChatGPT桌面端,全面支持Windows和macOS系统!这款新工具为用户在日常生活和工作中提供了前所未有的无缝交互体验。对于那些依赖桌面端进行开发工作的专业人士来说,这一更新带来了令人…...
香港站群服务器有助于提升网站在搜索引擎中的排名
拥有253个IP的服务器通常被称为多IP站群服务器。这种服务器架构主要用于集中管理多个网站,允许网站管理员通过一个后台管理系统来高效管理和更新这些网站。 一、主要特点 集中管理:多IP站群服务器通过统一的后台管理系统,可以实现对多个网站…...
YOLOX:使用自己数据集训练模型及改进--1.YOLOX环境搭建及运行
YOLOX环境搭建及运行 YOLO X网络架构是继YOLO v5后,由旷视科技于2021年提出的新一代anthor-free模型,研究者将网络分为输入端、Backbone、PAFPN及Predication,并在Predication提出Decoupled Head、Anchor-free和Multi positives(后文会详细介绍)。 本篇文章介绍如何通过官…...
PyTorch使用教程-深度学习框架
PyTorch使用教程-深度学习框架 1. PyTorch简介 1.1-什么是PyTorch PyTorch是一个广泛使用的开源机器学习框架,特别适合深度学习的应用。它以其动态计算图而闻名,允许在运行时修改模型,使得实验和调试更加灵活。PyTorch提供了强大的GPU加…...
TON商城与Telegram App:生态融合与去中心化未来的精彩碰撞
随着区块链技术的快速发展,去中心化应用(DApp)逐渐成为了数字生态的重要组成部分。而Telegram作为全球领先的即时通讯应用,不仅仅满足于传统的社交功能,更在区块链领域大胆探索,推出了基于其去中心化网络的…...
“乐鑫组件注册表”简介
当启动一个新的开发项目时,开发者们通常会利用库和驱动程序等现有的代码资源。这种做法不仅节省时间,还简化了项目的维护工作。本文将深入探讨乐鑫组件注册表的概念及其核心理念,旨在指导您高效地使用和贡献组件。 概念解析 ESP-IDF 的架构…...
凹凸/高度贴图、法线贴图、视差贴图、置换贴图异同
参考: 凹凸贴图、法线贴图、置换贴图-CSDN博客 视差贴图 - LearnOpenGL CN 1,Learn about Parallax(视差贴图) - 知乎 “视差贴图”的工作流程及原理(OpenGL) - 哔哩哔哩 法线与置换贴图原理讲解以及烘焙制作! - 知乎 1. Bump Mapping 凹凸贴图 BumpMap…...
ZSTD 内存泄漏问题
优质博文:IT-BLOG-CN Zstandard(简称zstd)是一种无损压缩算法,由Facebook开发并开源。它旨在提供高压缩比和高解压速度的平衡,适用于多种数据压缩需求。 特点 【1】高压缩比: zstd能够在保持较高压缩比的…...
c# npoi操作excel
今天在弄使用npoi对excel表的操作,遇到个问题就是使用workbook通过filestream打开后,让后workbook.write(filestream)居然报文件流关闭了,无法写入,弄了好久都不行,最后通过写2个excel文件来解决,现在看来我…...
十二:HTTP错误响应码:理解与应对
在现代网络技术中,HTTP(超文本传输协议)是浏览器与服务器之间沟通的基础。每当我们访问网站或发送请求,HTTP会返回一个响应码,这些代码不仅可以表示成功,还可以指示各种问题。本文将以HTTP错误响应码为主题,探讨其含义、常见类型及应对措施。 1. 400 Bad Request - 请求…...
Rust学习(六):函数式编程
Rust学习(六):函数式编程 我们在前一篇博客中已经介绍了如何通过trait和impl实现Rust的面向对象编程,但是Rust本身实际上并不提倡通过类来解决问题。Rust推崇的是函数式编程,强调将函数作为参数值或者其他函数的返回值…...
使用 Vue 和 Create-Vue 构建工程化前端项目
目录 前言1. 工程化的意义与 Vue 的生态支持2. 搭建 Vue 工程化项目2.1 环境准备2.2 使用 create-vue 创建项目2.2.1 初始化项目2.2.2 安装依赖2.2.3 本地运行 3. Vue 项目的目录结构解析4. Vue 开发流程详解4.1 项目入口与根组件4.1.1 main.js 的作用4.1.2 App.vue 的结构 4.2…...
opencv图片明暗度判断方法
OpenCV 的LAB 颜色空间(也称为 CIELAB)是一种颜色对手的颜色模型,它旨在模仿人类的色彩感知。LAB 颜色空间由三个分量组成: L: 亮度分量 (Lightness),范围从 0(黑色)到 100(白色&…...
QT6学习第三天
QT6学习第三天 第一个Widgets项目创建项目项目界面简单介绍编译文件介绍 我在第一天中将重点标了颜色,后边我把一些简单的东西都不写了,写了的都是实际用的东西,就不标颜色了。 第一个Widgets项目 首先我们创建一个widgets项目,…...
计算机网络-MSTP基础实验一(单域多实例)
前面我们已经大致了解了MSTP的基本概念和工作原理,但是我自己也觉得MSTP的理论很复杂不结合实验是很难搞懂的,今天来做一个配套的小实验以及一些配置命令。 一、网络拓扑 单域多实例拓扑 基本需求:SW1为VLAN10的网关,SW2为VLAN20的…...
React合成事件及其核心思想详解
相关联Javascript知识 1.JavaScript 的事件流 事件流是 JavaScript 处理事件的机制,它描述了事件从发生到被处理的过程。事件流主要包括两个阶段:捕获阶段和冒泡阶段。在捕获阶段,事件从文档的根元素开始,逐层向下传播到目标元素&…...
Datawhale模型减肥秘籍Tasking之模型量化
Datawhale模型减肥秘籍Tasking之模型量化 什么是量化?为什么量化?量化基本方法基于k-means的量化线性量化 训练后量化量化粒度动态量化参数的计算 ( Cliping )指数移动平均(EMA)Min-MaxKL 量化均方误差(MSE)…...
洛阳建设委员会网站/南宁百度seo排名
原标题:知识分享丨蓝牙电话功能操作指导什么是无线蓝牙技术:无线蓝牙技术是基于短距离的无线网络技术,使用 2402MHz ~ 2480MHz 的频率去让不同 的设备在短距离里连接。支持电脑端、外部设备、手机端、掌上电脑等各种不同的电子设备࿰…...
一个人怎么做网站/搜索引擎优化seo课程总结
无符号数和有符号数 (一)无符号数 即没有符号的数,机器字长相同时,无符号数和有符号数的范围是不同的。以机器字长16位为例,无符号数的范围是0~65 535,而有符号数的范围是-32 768 ~ 32 767。 ࿰…...
企业网站管理系统如何使用说明/网站策划方案
题目:原题链接(简单) 标签:常识 解法时间复杂度空间复杂度执行用时Ans 1 (Python)O(1)O(1)O(1)O(1)O(1)O(1)40ms (52.54%)Ans 2 (Python)Ans 3 (Python) 解法一: class Solution:def numberOfDays(self, Y: int, M:…...
重庆建设网站哪家专业/在线html5制作网站
在 js中,当我们需要重复使用一个字段,会将它定义为一个变量,在多个地方使用 在svg中,当我们需要重复使用一个图形时,要怎么处理呢? 一、通过<use>&<defs>…...
网站名称去哪里注册/杭州百度
请进入链接http://www.cnblogs.com/code-cd/p/4810408.html 转载于:https://www.cnblogs.com/xhc1263478959/p/4823950.html...
wordpress 后台主题/免费永久注册顶级域名网站
http://blog.csdn.net/leagoal/article/details/5705094...