当前位置: 首页 > news >正文

数据结构-4.栈与队列

本篇博客给大家带来的是栈和队列的知识点, 其中包括两道面试OJ题 用队列实现栈 和 用栈实现队列.

文章专栏: Java-数据结构

若有问题 评论区见

欢迎大家点赞 评论 收藏 分享

如果你不知道分享给谁,那就分享给薯条, 如果分享不成功, 那我就会回你一下,那样你就分享成功啦.

你们的支持是我不断创作的动力 .

1.栈(Stack)

1.1概念

栈: 一种特殊的线性表, 只许在固定的一端进行插入和删除元素操作. 进行数据插入和删除操作的一端称为栈顶, 另一端称为栈底. 栈中的数据元素遵守后进先出的原则.

在栈顶入数据称为压栈, 在栈顶出数据称为出栈.

1.2栈的使用

public static void main(String[] args) {Stack<Integer> stack = new Stack<>();stack.push(12);stack.push(23);stack.push(34);System.out.println(stack.size());//获取栈中有效元素个数-->4System.out.println(stack.peek());//获取栈顶元素-->4Integer x = stack.pop();//获取并删除栈顶元素System.out.println(x);System.out.println(stack.isEmpty());//判断栈是否为空.}

1.3 栈的模拟实现

Stack继承了Vector,  Vector 和 ArrayList 类似, 都是动态的顺序表, 不同的是Vector是线程安全的。

栈 是由 顺序表实现的,所以操作与顺序表大致相同.

public class MyStack {private int[] elem;private int usedSize;private static final int DEFAULT_CAPACITY = 10;public MyStack() {this.elem = new int[DEFAULT_CAPACITY];}//新增元素public void push(int val) {if(isFull()) {//空间不足,扩二倍.this.elem = Arrays.copyOf(this.elem, 2 * this.elem.length);}this.elem[usedSize] = val;usedSize++;}public boolean isFull() {return usedSize == elem.length;}public int pop() {if(isEmpty()) {System.out.println("栈为空");/*throw new EmptyException();*/}int OldVal = elem[usedSize-1];usedSize--;return OldVal;}public int peek() {if(isEmpty()) {System.out.println("栈为空");/*throw new EmptyException();*/}return elem[usedSize-1];}private boolean isEmpty() {return usedSize == 0;}}

1.4栈的应用场景

1. 改变元素的序列

2. 将递归转化为循环

1.5概念区分

栈 , 虚拟机栈 , 栈帧有什么区别 ?

本章所学的栈为数据结构栈,  虚拟机栈是内存当中的一块区域.

每次调用方法都需要在栈上给方法开辟一块内存,这块内存就是栈帧.

2.队列(Queue)

2.1概念

队列: 只允许在一端进行插入数据操作, 在另一端进行删除数据操作的特殊线性表, 队列具有先进先出特性, 进行插入操作的一段称为队尾, 这一操作是入队列.进行删除操作的一端称为队头,这一操作称为出队列.

2.2队列的使用

在Java中,Queue是个接口, 底层是通过链表实现的.

public static void main(String[] args) {Queue<Integer> queue = new LinkedList<>();queue.offer(1);queue.offer(2);queue.offer(3);//从队尾入队列.System.out.println(queue.size());//队列长度System.out.println(queue.poll());//删除并返回队头元素System.out.println(queue.peek());//瞄一眼队头元素if(queue.isEmpty()) {System.out.println("队列为空");}else {System.out.println(queue.size());}}

2.3队列模拟实现


public class MyLinkedListQueue {class ListNode {ListNode prev;ListNode next;int val;public ListNode(int val) {this.val = val;}}ListNode head;ListNode last;private int usedSize = 0;//插入元素public void offer(int val) {ListNode node = new ListNode(val);if(isEtmpty()) {head = last = node;usedSize++;}else {last.next = node;node.prev = last;last = node;usedSize++;}}//删除队头节点并返回其元素值public int poll() {if(isEtmpty()) {return -1;}else {//只有一个节点if(head.next == null) {int ret1 = head.val;head = last = null;usedSize--;return ret1;}//两个节点及以上:int ret2 = head.val;head = head.next;head.prev = null;usedSize--;return ret2;}}//peek头节点的值public int peek() {if(isEtmpty()) {return -1;}else {return head.val;}}//得到数据个数public int getUsedSize() {return usedSize;}public boolean isEtmpty() {return usedSize == 0;}
}

2.4循环队列

实际中我们有时还会使用一种队列叫循环队列。如操作系统课程讲解生产者消费者模型时可以就会使用循环队列。 环形队列通常使用数组实现。
先来看循环队列怎么插入元素
队头和队尾都处于0下标处, 那么rear = front时,队列为空. 从0下标处开始插入元素.
当rear走到 7 下标时, rear 如果继续++, rear=8越界, 所以rear不能简单的++.   又想让rear回到0下标.  可以rear = (rear+1)%elem.length; 
622. 设计循环队列 - 力扣(LeetCode)按照上面的思路写一写这道OJ题, 答案如下:
class MyCircularQueue {private int[] elem;private int front;private int rear;public MyCircularQueue(int k) {this.elem = new int[k+1];}public int Front() {if(!isEmpty()) {return elem[front];}return -1;}public int Rear() {if(!isEmpty()) {int index = (rear == 0) ? elem.length - 1 : rear-1;return elem[index];}return -1;}public boolean enQueue(int value) {if(isFull()) {return false;}elem[rear] = value;rear = (rear+1)%elem.length;return true;}public boolean deQueue() {if(isEmpty()) {return false;}front = (front+1)%elem.length;return true;}//检查队列是否为空public boolean isEmpty() {return rear == front;}//检查队列是否已满public boolean isFull() {return (rear+1)%elem.length == front;}
}

3.栈与队列互相实现的OJ题

225. 用队列实现栈 - 力扣(LeetCode)

1. 入栈怎么入呢?定义两个队列qu1和qu2,  都为空默认入到qu1,  只有一个为空,就是哪个不为空入哪个, 都不为空入到qu1.

public void push(int x) {if(!qu1.isEmpty()) {qu1.offer(x);}else if(!qu2.isEmpty()) {qu2.offer(x);}else {qu1.offer(x);}}

2. 出栈怎么出呢?画图分析,不难得出实现栈至少需要两个队列.

两个队列怎么做到先出45呢?

执行上图操作后, 再出qu1队头元素,就做到了先出45. 

接着 如果要删除34也是一样的, 先把12和23在 qu2出队 到 qu1...

public int top() {if(empty()) {return -1;}if(!qu1.isEmpty()) {int tmp = 0;int size = qu1.size();for (int i = 0; i < size; i++) {tmp = qu1.poll();qu2.offer(tmp);}return tmp;}else {int size = qu2.size();int tmp1 = 0;for (int i = 0; i < size; i++) {tmp1 = qu2.poll();qu1.offer(tmp1);}return tmp1;}}public boolean empty() {return qu1.isEmpty() && qu2.isEmpty();}
}

整道题的答案 

class MyStack {private Queue<Integer> qu1;private Queue<Integer> qu2;public MyStack() {qu1 = new LinkedList<>();qu2 = new LinkedList<>();}public void push(int x) {if(!qu1.isEmpty()) {qu1.offer(x);}else if(!qu2.isEmpty()) {qu2.offer(x);}else {qu1.offer(x);}}public int pop() {if(empty()) {return -1;}if(!qu1.isEmpty()) {int size = qu1.size();for (int i = 0; i < size-1; i++) {int tmp = qu1.poll();qu2.offer(tmp);}return qu1.poll();}else {int size = qu2.size();for (int i = 0; i < size-1; i++) {int tmp = qu2.poll();qu1.offer(tmp);}return qu2.poll();}}public int top() {if(empty()) {return -1;}if(!qu1.isEmpty()) {int tmp = 0;int size = qu1.size();for (int i = 0; i < size; i++) {tmp = qu1.poll();qu2.offer(tmp);}return tmp;}else {int size = qu2.size();int tmp1 = 0;for (int i = 0; i < size; i++) {tmp1 = qu2.poll();qu1.offer(tmp1);}return tmp1;}}public boolean empty() {return qu1.isEmpty() && qu2.isEmpty();}
}

232. 用栈实现队列 - 力扣(LeetCode)

1. 入队, 将所有元素入到第一个栈中 s1.

2.出队, 把第一个栈中所有元素全部倒回第二个栈中, 出s2 的栈顶元素即可.

class MyQueue {Stack<Integer> s1;Stack<Integer> s2;public MyQueue() {s1 = new Stack<>();s2 = new Stack<>();}public void push(int x) {s1.push(x);}public int pop() {if(empty()) {return -1;}if(s2.empty()) {while(!s1.empty()) {s2.push(s1.pop());}}return s2.pop();}public int peek() {if(empty()) {return -1;}if(s2.empty()) {while(!s1.empty()) {s2.push(s1.pop());}}return s2.peek();}public boolean empty() {return s1.size() == 0 && s2.size() == 0;}
}

以上就是本文的全部内容了, 感谢观看!!!

相关文章:

数据结构-4.栈与队列

本篇博客给大家带来的是栈和队列的知识点, 其中包括两道面试OJ题 用队列实现栈 和 用栈实现队列. 文章专栏: Java-数据结构 若有问题 评论区见 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条, 如果分享不成功, 那我就会回你一下,那样你就分享成功啦. 你们的…...

芝士AI写作有什么特色? 大模型支撑,智能改写续写,让写作更轻松

又到了一年的毕业季&#xff0c;大学四年眨眼间匆匆就过去了&#xff0c;毕业&#xff0c;求职&#xff0c;考研&#xff0c;工作&#xff0c;升学&#xff0c;但是在这之前&#xff0c;我们必须要完成论文的写作&#xff0c;这也是每一位大学生都必须要面对~ 芝士AI官网&…...

【计网】从零开始学习http协议 --- http的请求与应答

如果你不能飞&#xff0c;那就跑&#xff1b; 如果跑不动&#xff0c;那就走&#xff1b; 实在走不了&#xff0c;那就爬。 无论做什么&#xff0c;你都要勇往直前。 --- 马丁路德金 --- 从零开始学习http协议 1 什么是http协议2 认识URL3 http的请求和应答3.1 服务端设计…...

记录linux环境下搭建本地MQTT服务器实现mqtt的ssl加密通讯

1、ubuntu安装mosquitto sudo apt-get update//安装服务端 sudo apt-get install mosquitto//安装客户端 sudo apt-get install mosquitto-clients 2、安装openssl 3、mqtts/tls加密传输 mosquitto原生支持了TLS加密&#xff0c;TLS&#xff08;传输层安全&#xff09;是SSL&…...

基于python+django+vue的电影数据分析及可视化系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…...

HJ50-四则运算:栈的运用、中缀表达式转后缀表达式并计算结果

文章目录 题目一、分析1.1表达式预处理1.2中缀表达式转后缀1.3 后缀表达式计算结果 二、答案 题目 一、分析 通过利用栈将中缀表达式转换为后缀表达式&#xff0c;在根据后缀表达式计算运算结果。由于包含负数操作数的情况&#xff0c;并且操作数位数不固定为1&#xff0c;因此…...

C++编程:实现简单的高精度时间日志记录小程序

0. 概述 为了检查是否存在系统时间跳变&#xff0c;本文使用C实现了一个简单的高精度时间日志记录小程序。该程序能够每隔指定时间&#xff08;默认40毫秒&#xff09;记录一次系统时间到文件中&#xff0c;并具备以下功能&#xff1a; 自定义时间间隔和文件名&#xff1a;通…...

QQ机器人搭建

使用QQ官方机器人Python SDK和三方框架搭建QQ群聊机器人 文章目录 使用QQ官方机器人Python SDK和三方框架搭建QQ群聊机器人前言编写机器人代码机器人监听群聊进行文字回复机器人监听群聊进行图片回复机器人监听群聊进行文件发送机器人监听群聊进行视频发送机器人监听群聊进行语…...

flink设置保存点和恢复保存点

增加了hdfs package com.qyt;import org.apache.flink.api.java.functions.KeySelector; import org.apache.flink.api.java.tuple.Tuple2;import org.apache.flink.runtime.state.storage.FileSystemCheckpointStorage;import org.apache.flink.streaming.api.datastream.Dat…...

使用python获取百度一下,热搜TOP数据详情

一、查找对应链接 # 警告&#xff1a;以下代码仅供学习和交流使用&#xff0c;严禁用于任何违法活动。 # 本代码旨在帮助理解和学习编程概念&#xff0c;不得用于侵犯他人权益或违反法律法规的行为。 1、打开百度页面 百度一下&#xff0c;你就知道 2、点击F12 或 右键鼠标…...

Go conc库学习与使用

文章目录 主要功能和特点conc 的安装典型使用场景示例代码并行执行多个 Goroutines错误处理限制并发 Goroutines 数量使用 context.Context 进行任务控制 常见问题1. **任务中发生 panic**原因&#xff1a;解决方法&#xff1a; 2. **conc.Group 重复调用 Wait()**原因&#xf…...

大模型prompt先关

对于未出现的任务&#xff0c;prompt编写技巧&#xff1a; 1、假设你是资深的摘要生成专家&#xff0c;根据提供的内容&#xff0c;总结对应的摘要信息。请生成一个指令&#xff0c;指令中带有一个使用例子。直接提供给大型模型以执行此任务。 2、基于大模型提供的内容再进行二…...

尚品汇-自动化部署-Jenkins的安装与环境配置(五十六)

目录&#xff1a; 自动化持续集成 &#xff08;1&#xff09;环境准备 &#xff08;2&#xff09;初始化 Jenkins 插件和管理员用户 &#xff08;3&#xff09;工作流程 &#xff08;4&#xff09;配置 Jenkins 构建工具 自动化持续集成 互联网软件的开发和发布&#xf…...

【尚跑】2024铜川红色照金半程马拉松赛,大爬坡152安全完赛

1、赛事背景 2024年9月22日8点&#xff0c;2024铜川红色照金半程马拉松赛于照金1933广场鸣枪起跑&#xff01; 起跑仪式上&#xff0c;6000位选手们合唱《歌唱祖国》&#xff0c;熟悉的旋律响彻陕甘边革命根据地照金纪念馆前&#xff0c;激昂的歌声凝聚心中不变的热爱。随着国…...

WPS中让两列数据合并的方法

有这样一个需求&#xff0c;就是把A列数据和B列数据进行合并&#xff08;空单元格略过&#xff09;具体实现效果如图下&#xff1a; 该如何操作呢&#xff1f; 首先在新的一列第一个单元格中输入公式"A1&B1" 然后回车&#xff0c;就出现了两列单元格数据合并的效…...

使用yum为centos系统安装软件以及使用(包含阿里云yum源配置)

centos系统配置阿里云yum源 因为centos7官方停止维护&#xff0c;自带yum源用不了了&#xff0c;所以可以更换成阿里云yum源 方法&#xff1a; 使用root权限执行以下语句 curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo CentOS…...

《深度学习》【项目】OpenCV 发票识别 透视变换、轮廓检测解析及案例解析

目录 一、透视变换 1、什么是透视变换 2、操作步骤 1&#xff09;选择透视变换的源图像和目标图像 2&#xff09;确定透视变换所需的关键点 3&#xff09;计算透视变换的变换矩阵 4&#xff09;对源图像进行透视变换 5&#xff09;对变换后的图像进行插值处理 二、轮廓检测…...

Linux 线程互斥

前言 对于初学线程的伙伴来讲&#xff0c;多线程并发访问导致的数据不一致问题&#xff0c;总是让人陷入怀疑&#xff0c;很多人只是给你说加锁&#xff01;但没有人告诉你为什么&#xff1f;本篇博客将详解&#xff01; 目录 前言 一、线程互斥 • 为什么票会出现负数的情…...

【Redis 源码】6AOF持久化

1 AOF功能说明 aof.c 文件是 Redis 中负责 AOF&#xff08;Append-Only File&#xff09;持久化的核心文件。AOF 持久化通过记录服务器接收到的每个写命令来实现数据的持久化。这样&#xff0c;在 Redis 重启时&#xff0c;可以通过重放这些命令来恢复数据。 2 AOF相关配置 a…...

6.MySQL基本查询

目录 表的增删查改Insert&#xff08;插入&#xff09;插入替换插入替换2 Retrieve&#xff08;查找&#xff09;SELECT 列全列查找指定列查询查询字段为表达式为查询结果指定别名结果去重 WHERE 条件order by子句筛选分页结果 Update&#xff08;更新&#xff09;delete&#…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...