数据结构(二)队列和栈

Java提供了java.util.Stack类来表示栈数据结构。Stack类是Vector类的子类,它实现了一个标准的后进先出(LIFO)栈。同样也提供了Queue接口,表示一系列按照特定顺序排列的元素,其中最早添加的元素将最先被移除(先进先出,FIFO)。并且Deque(双端队列,Double Ended Queue)扩展了Queue接口,提供了在队列两端进行插入和删除操作的方法。Deque允许在队列的两端进行元素的添加、获取和移除操作,因此可以用来实现栈、队列等数据结构。

但是今天仅仅用最简单的数组完成队列和栈的实现

队列

队列(Queue)是一种常见的线性数据结构,它按照先进先出(First-In-First-Out,FIFO)的原则管理元素。换句话说,最先添加到队列中的元素将首先被移除。队列通常具有两个主要操作:入队(Enqueue)和出队(Dequeue)。入队操作将元素添加到队列的尾部,而出队操作则将队列的头部元素移除并返回。

需求分析

首先作为对数组的封装,容量 capacityT[] queue必不可少

其次,目前队列中的元素个数 size 也要记录下来、

最后就是两个指针,一个指向head, 另一个指向tail

public class ArrayQueue {private int[] queue; // 用于存储元素的数组private int capacity; // 队列的容量private int size; // 队列中元素的个数private int head; // 队列头部指针private int tail; // 队列尾部指针// 构造函数,初始化队列public ArrayQueue(int capacity) {this.capacity = capacity;queue = new int[capacity];size = 0;head = 0;tail = -1;}
}

作为队列,肯定需要放置元素,取出元素以及其他容器的基本操作。

判断元素个数,是否为空或满

    // 判断队列是否为空public boolean isEmpty() {return size == 0;}// 判断队列是否已满public boolean isFull() {return size == capacity;}// 获取队列中元素的个数public int size() {return size;}

放置元素

    // 向队列尾部添加元素public void enqueue(int element) {if (isFull()) {throw new IllegalStateException("Queue is full");}tail = (tail + 1) % capacity;queue[tail] = element;size++;}

获取元素

获取元素有两种选择,

一,获取并移除元素

    // 从队列头部移除元素并返回public int dequeue() {if (isEmpty()) {throw new IllegalStateException("Queue is empty");}int removed = queue[head];head = (head + 1) % capacity;size--;return removed;}

二,只获取不移除元素

    // 获取队列头部元素但不移除public int peek() {if (isEmpty()) {throw new IllegalStateException("Queue is empty");}return queue[head];}

完整代码

public class ArrayQueue {private int[] queue; // 用于存储元素的数组private int capacity; // 队列的容量private int size; // 队列中元素的个数private int head; // 队列头部指针private int tail; // 队列尾部指针// 构造函数,初始化队列public ArrayQueue(int capacity) {this.capacity = capacity;queue = new int[capacity];size = 0;head = 0;tail = -1;}// 向队列尾部添加元素public void enqueue(int element) {if (isFull()) {throw new IllegalStateException("Queue is full");}tail = (tail + 1) % capacity;queue[tail] = element;size++;}// 从队列头部移除元素并返回public int dequeue() {if (isEmpty()) {throw new IllegalStateException("Queue is empty");}int removed = queue[head];head = (head + 1) % capacity;size--;return removed;}// 获取队列头部元素但不移除public int peek() {if (isEmpty()) {throw new IllegalStateException("Queue is empty");}return queue[head];}// 判断队列是否为空public boolean isEmpty() {return size == 0;}// 判断队列是否已满public boolean isFull() {return size == capacity;}// 获取队列中元素的个数public int size() {return size;}public static void main(String[] args) {ArrayQueue queue = new ArrayQueue(5);queue.enqueue(1);queue.enqueue(2);queue.enqueue(3);System.out.println("Dequeued: " + queue.dequeue()); // 输出:Dequeued: 1System.out.println("Peek: " + queue.peek()); // 输出:Peek: 2}
}

栈(Stack)是一种常见的线性数据结构,它遵循后进先出(Last-In-First-Out,LIFO)的原则。换句话说,最后添加到栈中的元素将首先被移除。栈通常具有两个主要操作:压入(Push)和弹出(Pop)。压入操作将元素添加到栈顶,而弹出操作则将栈顶的元素移除并返回。

需求分析

其实基本同上,不过栈只需要一个size就够,无需head,tail索引。

public class ArrayStack {private int[] array; // 用于存储元素的数组private int size; // 栈中元素的个数// 构造函数,初始化指定容量的栈public ArrayStack(int capacity) {array = new int[capacity];size = 0;}
}

其余需求也就是这些,和队列基本一致。

  • 压入(Push): 向栈顶添加一个元素。
  • 弹出(Pop): 从栈顶移除一个元素,并返回移除的元素。
  • 查看栈顶元素(Peek): 返回栈顶的元素但不移除。
  • 判空(isEmpty): 检查栈是否为空。
  • 获取栈的大小(Size): 返回栈中元素的个数。

考虑到一端进出,栈可以实现自动扩容。

元素个数,是否为空

    // 判断栈是否为空public boolean isEmpty() {return size == 0;}// 获取栈中元素的个数public int size() {return size;}

取元素

如上,有放回和无放回

    // 弹出栈顶元素并返回public int pop() {if (isEmpty()) {throw new IllegalStateException("Stack is empty");}int removed = array[--size];array[size] = 0; // 用于清除被移除元素的引用if (size > 0 && size == array.length / 4) {resize(array.length / 2); // 缩容}return removed;}// 获取栈顶元素但不移除public int peek() {if (isEmpty()) {throw new IllegalStateException("Stack is empty");}return array[size - 1];}

resize函数下面会讲。

放置元素

这里我们判断是否已满,满了就扩容

    // 压入元素到栈顶public void push(int element) {if (size == array.length) {resize(2 * array.length); // 扩容}array[size++] = element;}

动态扩缩容

resize就是扩(缩)容函,实现如下

    // 调整栈的容量private void resize(int newCapacity) {int[] newArray = new int[newCapacity];for (int i = 0; i < size; i++) {newArray[i] = array[i];}array = newArray;}

全部代码

public class ArrayStack {private int[] array; // 用于存储元素的数组private int size; // 栈中元素的个数// 构造函数,初始化指定容量的栈public ArrayStack(int capacity) {array = new int[capacity];size = 0;}// 压入元素到栈顶public void push(int element) {if (size == array.length) {resize(2 * array.length); // 扩容}array[size++] = element;}// 弹出栈顶元素并返回public int pop() {if (isEmpty()) {throw new IllegalStateException("Stack is empty");}int removed = array[--size];array[size] = 0; // 用于清除被移除元素的引用if (size > 0 && size == array.length / 4) {resize(array.length / 2); // 缩容}return removed;}// 获取栈顶元素但不移除public int peek() {if (isEmpty()) {throw new IllegalStateException("Stack is empty");}return array[size - 1];}// 判断栈是否为空public boolean isEmpty() {return size == 0;}// 获取栈中元素的个数public int size() {return size;}// 调整栈的容量private void resize(int newCapacity) {int[] newArray = new int[newCapacity];for (int i = 0; i < size; i++) {newArray[i] = array[i];}array = newArray;}public static void main(String[] args) {ArrayStack stack = new ArrayStack(10);stack.push(1);stack.push(2);stack.push(3);System.out.println("Popped: " + stack.pop()); // 输出:Popped: 3System.out.println("Peek: " + stack.peek()); // 输出:Peek: 2}
}

总结

  • 栈和队列都是线性数据结构,但它们的操作顺序和特性不同,适用于不同的应用场景。
  • 栈常用于需要后进先出操作的场景,例如函数调用、表达式求值等。
  • 队列常用于需要先进先出操作的场景,例如任务调度、消息传递等。
  • 栈和队列都可以使用数组或链表来实现,具体选择取决于应用场景和需求。

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

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

相关文章

SAP HCM 0008信息类型间接评估与直接评估

如果在间接评估模块输入就是间接评估&#xff08;tarif是读取下图中的数据 a代表不需要输入工资项&#xff0c;b表示需要找工资相&#xff09; 不输入就是直接评估需要客户自己输入数字 第2个情况 summe求和 &#xff08;比如在0008中输入9000与9001 那么自动求出9002工资项数…

C# WPF编程-布局

C# WPF编程-布局 布局WPF布局原则布局过程布局容器布局属性Border控件StackPanel布局WrapPanel布局DockPanel布局Grid布局UniformGrid布局Canvas布局 布局 WPF布局原则 WPF窗口只能包含单个元素。为在WPF窗口中放置多个元素并创建更贴近实用的用户界面&#xff0c;需要在窗口…

uniapp 之 一些常用方法的封装(页面跳转,页面传参等)

util.js 提示&#xff1a;permission.js是uniapp插件市场由官方DCloud_heavensoft提供的App权限判断和提示插件。 import permision from "/js_sdk/wa-permission/permission.js"/*** uni.toast 封装* param {String} msg toast 提示内容* param {Number} duration …

SpringBoot项目如何打包成war包,并部署在tomcat上运行

项目场景&#xff1a; 正常情况下&#xff0c;我们开发 SpringBoot 项目&#xff0c;由于内置了Tomcat&#xff0c;所以项目可以直接启动&#xff0c;部署到服务器的时候&#xff0c;直接打成 jar 包&#xff0c;就可以运行了。 有时我们会需要打包成 war 包&#xff0c;放入外…

Redis进阶(持久化、复制、集群、多线程、缓存)

Redis进阶 1.Redis持久化1.1 什么是Redis持久化&#xff1f;为什么需要持久化&#xff1f;1.2 Redis持久化方式——RDB(Redis DataBase)1.2.1 什么是RDB&#xff1f;1.2.2 备份文件位置1.2.3 触发RDB的方式1.2.3.1 自动触发1.2.3.2 手动触发1.2.3.3 其他触发方式 1.2.4 RDB优缺…

【GPT概念04】仅解码器(only decode)模型的解码策略

一、说明 在我之前的博客中&#xff0c;我们研究了关于生成式预训练转换器的整个概述&#xff0c;以及一篇关于生成式预训练转换器&#xff08;GPT&#xff09;的博客——预训练、微调和不同的用例应用。现在让我们看看所有仅解码器模型的解码策略是什么。 二、解码策略 在之前…

阿里云代理仓库地址

在天朝使用jcenter、mavenCentral及google三个远程仓库&#xff0c;Gradle Sync会很慢&#xff0c;google仓库甚至需要科学上网才能访问。为了加快Gradle Sync速度&#xff0c;一招教你优先用 阿里云仓库服务 的仓库作为下载源。 一劳永逸之道 将本项目的gradle/init.d/init.g…

【小程序开发】功能页面 API 汇总集合

ty.device.openCategoryActivatorPage 进入配网-选品类首页 需引入DeviceKit&#xff0c;且在>2.3.2版本才可使用 参数 Object object 属性类型默认值必填说明completefunction否接口调用结束的回调函数&#xff08;调用成功、失败都会执行&#xff09;successfunction否…

【Jenkins】Spark on Yarn 部署脚本

文章目录 停止 Yarn 集群中的 Spark 应用提交 Spark 应用到 YARN✔️ 目标:提供 Jenkins 脚本,用于 在 Jenkins 中实现 Spark 任务提交到 YARN 及重启操作。 停止 Yarn 集群中的 Spark 应用 Shell 脚本: # 停止spark应用(仅支持一个yarn应用,如果跑了多个应用,会报错)…

【Linux】多线程编程基础

&#x1f4bb;文章目录 &#x1f4c4;前言&#x1f33a;linux线程基础线程的概念线程的优缺点线程与进程的区别 线程的创建 &#x1f33b;linux线程冲突概念互斥锁函数介绍加锁的缺点 &#x1f4d3;总结 &#x1f4c4;前言 无论你是否为程序员&#xff0c;相信多线程这个词汇应…

How to install Miniconda on ubuntu 22.04

How to install Miniconda on ubuntu 22.04 介绍安装脚本细节 初始化脚本细节 卸载脚本细节 介绍 通常来说&#xff0c;要安装conda有以下三种安装方案&#xff1a; Miniconda Miniconda 是 conda 的免费最小安装程序。它是 Anaconda 的一个小型引导版本&#xff0c;仅​​包…

量子计算机

近日&#xff0c;在AWS re&#xff1a;Invent全球大会上&#xff0c;亚马逊官宣AWS三箭齐发量子计算组合拳&#xff1a;Braket、AWS量子计算中心和量子解决方案实验室。 随着亚马逊的强势入局&#xff0c;加上此前鼓吹量子霸权的谷歌、起步最早的IBM、暗自发力的微软&#xff…

Android仿微信视频聊天本地与远程切换功能

一、xml布局 <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-auto&qu…

react-jsx

react04 jsx语法 - 01 基础知识&#xff1a; jsx javascript xml(html) 把js和heml标签混合到一起 react视图编写及构建的简要流程 &#xff1a; 如何在react中使vs code支持格式化和快捷键提示&#xff1a;1, 2,修改文件后缀为jsx&#xff0c;因为webpack的打包规则中可以…

如何通过idea搭建一个SpringBoot的Web项目(最基础版)

通过idea搭建一个SpringBoot的Web项目 文章目录 通过idea搭建一个SpringBoot的Web项目一、打开idea&#xff0c;找到 create new project二、创建方式三、配置项目依赖四、新建项目模块五、总结 一、打开idea&#xff0c;找到 create new project 方式1 方式2 二、创建方式 新…

BERT 论文阅读笔记

文章目录 前言论文阅读同类工作比较模型架构训练方式使用步骤实验结果 其他 前言 BERT是在NLP领域中第一个预训练好的大型神经网络&#xff0c;可以通过模型微调的方式应用于后续很多下游任务中&#xff0c;从而避免了下游NLP应用需要单独构建一个新的神经网络进行复杂的预训练…

合根植物。

4.合根植物 - 蓝桥云课 (lanqiao.cn) 题目描述 w星球的一个种植园&#xff0c;被分成mxn个小格子(东西方向m行&#xff0c;南北方向n列)。每个格子里种了一株合根植物 这种植物有个特点&#xff0c;它的根可能会沿着南北或东西方向伸展从而与另一个格子的植物合成为一体。 如果…

马斯克开源Grok-1

Grok-1是由马斯克AI创企xAI发布的第一代大语言模型&#xff0c;它以其巨大的参数量——高达3140亿&#xff0c;引起了全球范围内的广泛关注。这一参数量远超其他知名模型&#xff0c;如OpenAI的GPT-3.5&#xff0c;后者仅有1750亿参数。在2024年3月17日&#xff0c;马斯克宣布将…

【jvm】jinfo使用

jinfo介绍 jinfo 是一个命令行工具&#xff0c;用于查看和修改 Java 虚拟机&#xff08;JVM&#xff09;的配置参数。它通常用于调试和性能调优。 使用 jinfo 命令&#xff0c;你可以查看当前 JVM 的配置参数&#xff0c;包括堆大小、线程数、垃圾回收器类型等。此外&#xf…

天翼云防火墙配置端口转换案例

环境: 天翼云 云墙 问题描述: 天翼云防火墙配置端口转换案例 云主机192.168.10.9:2231 解决方案: 1.先登入云墙 可以从控制中心登入不用再输入密码 2.新建对象和端口 192.168.10.9:2231 3.到弹性IP这选个公网IP 记住弹性IP和后面虚拟IP 4.新建 目的NAT,按原有复制…