文章目录

  • 1.栈
    • 1.1 栈的定义
    • 1.2 栈的使用
    • 1.3 栈的模拟实现
  • 2.队列
    • 2.1 队列的定义
    • 2.2 队列的使用
    • 2.3 队列的模拟实现
  • 3.循环队列
    • 3.1 循环队列的概念
    • 3.2 循环队列判断空和满
  • 4.双端队列Deque


1.栈

1.1 栈的定义

栈是一种特殊的线性表,其只允许在固定的一段进行数据的插入或者删除。一般,插入或删除元素的一端叫栈顶,栈顶的另一端一般叫做栈底。栈中的元素均遵循后进先出(LIFO)的原则。

image-20250805103123153

1.2 栈的使用

栈的常用方法为:

方法功能
Stack()构造空栈
E push(E e)将元素入栈,并返回该元素
E pop()栈顶元素出栈并返回该元素
E peek()获取栈顶元素
int size()获取栈中的元素个数
boolean empty()判断栈是否为空
public static void main(String[] args) {Stack<Integer> s=new Stack<>();s.push(1);s.push(2);s.push(3);System.out.println("栈的大小为:"+s.size());System.out.println("栈顶元素为:"+s.peek());System.out.println("出栈元素为:"+s.pop());System.out.println("出栈后的栈顶元素为:"+s.peek());s.pop();s.pop();if(s.empty()) {System.out.println("当前栈为空");}
}

1.3 栈的模拟实现

image-20250805103721994

图中可以看出,Stack继承了Vector类,Vector和ArrayList类似,都是会动态增长的顺序表。

public class MyStack<E> {  private Object[] elem;private int elemSize;//构造方法public MyStack() {}public MyStack(int capacity) {}//元素入栈并返回public E push(E e) {}//元素出栈并返回public E pop() {}//获取栈顶元素public E peek() {}//获得栈中元素个数public int size() {}//判断是否为空栈public boolean empty() {}
}

1.入栈:

public E push(E e) {if(elem.length==elemSize) {this.elem=Arrays.copyOf(elem,2*elem.length);}elem[elemSize++]=e;return e;
}

2.出栈:

public E pop() {if(size()==0) {throw new RuntimeException("栈中不存在元素,无法删除");}E obj=peek();elemSize--;return obj;
}

3.获取栈顶元素

public E peek() {int len=size();if(len==0) {throw new RuntimeException("栈中不存在元素");}return (E)elem[len-1];
}

4.判空与获取大小

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

5.测试结果:

image-20250805123124671

2.队列

2.1 队列的定义

队列是一种特殊的线性表。其是只允许在一端进行插入,在另一端进行删除的结构

插入端即队尾(Tail/Rear),删除端为队头(Head/Front)。对元素的操作遵循先入先出(FIFO)的原则。

image-20250805130401181

2.2 队列的使用

image-20250805130340988

可以看到,LinkedList类实现了Queue接口,因此需要用LinkedList类来实例化对象;

方法功能
boolean offer(E e)将元素入队
E poll()队头元素出队并返回该元素
E peek()获取队头元素
int size()获取队列中的元素个数
boolean isEmpty()判断队列是否为空
public static void main(String[] args) {Queue<Integer> q=new LinkedList<>();q.offer(1);q.offer(2);q.offer(3);  //1,2,3System.out.println(q.poll()); System.out.println(q.peek());System.out.println("队列为空吗?"+q.isEmpty());
}

2.3 队列的模拟实现

队列的实现既可以用数组也可以用列表实现;虽然在Java中使用链表来实现队列,但其常数时间的并不是很好,因此,如果在刷题,尤其是竞赛等场景(数据量确定),用数组去模拟队列会是更好的写法;

这里使用双端链表来模拟实现:

public class MyQueue<E> {class ListNode{private E val;private ListNode prev;private ListNode next;public ListNode(E val) {this.val=val;}}private ListNode head;  //头指针private ListNode tail;  //尾指针private int usedSize;   //当前队列大小//元素从队尾入队列public boolean offer(E e) {}//队头元素出队列public E poll() {}//获取队头元素public E peek() {}//获取队列元素个数public int size() {return usedSize;}//判断队列是否为空public boolean isEmpty() {return usedSize==0;}
}

1.入队列:

public boolean offer(E e) {ListNode node=new ListNode(e);//空队列if(usedSize==0) {head=tail=node;}else {tail.next=node;node.prev=tail;tail=tail.next;}this.usedSize++;return true;
}

2.出队列:

public E poll() {if(usedSize==0) {throw new RuntimeException("当前队列为空");}E obj=head.val;if(head==tail) {head=tail=null;}else {head=head.next;head.prev=null;}usedSize--;return obj;
}

3.获取队头元素

public E peek() {if(usedSize==0) {throw new RuntimeException("队列为空");}return head.val;
}

4.测试结果:

image-20250806110838896

3.循环队列

3.1 循环队列的概念

循环队列简单来说就是一个将队列的首尾相连接的特殊队列;循环队列通常采用数组实现

image-20250806112059232

3.2 循环队列判断空和满

1.使用size记录循环队列大小

if(front==rear&&size==0)System.out.println("循环队列为空")
if(front==rear&&size!=0)System.out.println("循环队列为满")

2.使用标记

  1. 初始状态:队列为空,front==rear&&isFull=false
  2. 入队前,检查front与rear是否重合,重合则isFull=true,即队列满,否则rear移动
  3. 出队时,front移动,isFull=false

3.保留一个位置

image-20250806125717458

  • 队列为空:front==rear
  • 队列为满:(rear+1)%capacity
  • rear的循环移动:rear=(rear+1)%capacity

4.双端队列Deque

image-20250807100634548

双端队列是可以在两端均进行插入和删除的队列;即队头队尾均可以进行出队入队,

因此Deque既可以当作队列也可以当作栈使用

Deque是接口,因此使用时必须用LinkedList创建对象

Deque常见的实现类为:

Deque<Integer> stack=new ArrayDeque<>();
Deque<Integer> queue=new LinkedList<>();

-----------------------------------------------------------------------------完-----------------------------------------------------------------------------

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

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

相关文章

【性能测试】---测试工具篇(jmeter)

目录 1、安装并启动jemeter 2、重点组件 2.1、线程组&#xff1a; 2.2、HTTP取样器​编辑 2.3、查看结果树 2.4、HTTP请求默认值 2.5、HTTP信息头管理器 2.6、JSON提取器 2.7、JSON断言 2.8、同步定时器 2.9、CSV数据文件设置 2.10、HTTP Cookie管理器 3、测试报告…

机器学习(12):拉索回归Lasso

- 拉索回归可以将一些权重压缩到零&#xff0c;从而实现特征选择。这意味着模型最终可能只包含一部分特征。 - 适用于特征数量远大于样本数量的情况&#xff0c;或者当特征间存在相关性时&#xff0c;可以从中选择最相关的特征。 - 拉索回归产生的模型可能更简单&#xff0c;因…

Redis持久化存储

Redis持久化存储详解 一、核心持久化机制 Redis提供两种主要持久化方式&#xff1a;RDB&#xff08;快照&#xff09; 和 AOF&#xff08;追加文件&#xff09;&#xff0c;以及两者的混合模式。 RDB&#xff08;Redis Database&#xff09;快照持久化 工作原理 RDB通过创建数据…

python学智能算法(三十四)|SVM-KKT条件回顾

【1】引言 前序学习进程中&#xff0c;对软边界拉格朗日方程进行了初步构建。 其中约定了两个拉格朗日乘子要非负&#xff0c;其本质是要满足KKT条件。 今天就乘此次机会&#xff0c;在回顾一下KKT条件。 【2】定义 当问题无约束的时候&#xff0c;只要让函数梯度为零&#…

【网络基础】计算机网络发展背景及传输数据过程介绍

本文旨在帮助初学者建立起计算机网络的基础认知&#xff0c;从网络的发展背景到网络协议的分层模型&#xff0c;再到IP与MAC地址的基本概念&#xff0c;全面覆盖第一阶段学习重点。 &#x1f4cc; 本节重点 了解计算机网络的发展背景&#xff0c;掌握局域网&#xff08;LAN&am…

阿里云-通义灵码:解锁云原生智能开发新能力,让云开发更“灵”~

免责声明&#xff1a;此篇文章所有内容皆是本人实验&#xff0c;并非广告推广&#xff0c;并非抄袭&#xff0c;如有侵权&#xff0c;请联系笔者。 每日一句 信念其实就是相信未来&#xff0c; 相信内在&#xff0c; 以及坦然美好的心境。 目录 每日一句 一. 引言 二.通义…

lesson33:Python协程详解:从原理到实战的异步编程指南

目录 一、协程核心概念&#xff1a;轻量级并发的本质 1.1 什么是协程&#xff1f; 1.2 协程与线程/进程的对比 二、协程工作原理&#xff1a;事件循环与协作式调度 2.1 事件循环&#xff08;Event Loop&#xff09;&#xff1a;协程的"调度中心" 2.2 协作式调度…

深入理解C++模板进阶:非类型参数、特化与分离编译

前言C模板是泛型编程的核心&#xff0c;它允许我们编写与类型无关的代码。在掌握了模板的基础知识后&#xff0c;我们需要进一步了解模板的高级特性&#xff0c;以便更灵活地使用它们。本文将深入探讨三个重要的模板进阶主题&#xff1a;非类型模板参数、模板特化以及模板的分离…

使用winsw把SpringBoot项目注册成window服务

目录 一、使用winsw注册 1.1、项目打jar包 1.2、下载winsw 1.3、把 WinSW.NET4.exe 重新命名 1.4、编写m配置文件用于配置注册信息 1.5、创建文件夹存放你的文件 1.6、安装服务 1.7、启动服务 1.8、卸载服务 1.8、停止服务 一、使用winsw注册 1.1、项目打jar包 例如项目jar包名…

进阶向:Python开发简易QQ聊天机器人

数字化时代的聊天机器人应用在当今数字化时代&#xff0c;聊天机器人已经成为日常生活和商业活动中不可或缺的一部分。根据市场研究数据显示&#xff0c;全球聊天机器人市场规模预计将在2026年达到102亿美元&#xff0c;年复合增长率达到34.75%。这些智能助手正广泛应用于以下场…

基于开源链动2+1模式AI智能名片S2B2C商城小程序的用户留存策略研究

摘要&#xff1a;在数字化商业竞争白热化的当下&#xff0c;用户留存成为企业可持续发展的核心命题。本文聚焦开源链动21模式AI智能名片S2B2C商城小程序这一创新技术组合&#xff0c;通过分析其技术架构、模式创新与生态闭环的协同效应&#xff0c;揭示其在降低用户决策成本、提…

单词的划分(动态规划)

题目描述有一个很长的由小写字母组成字符串。为了便于对这个字符串进行分析&#xff0c;需要将它划分成若干个部分&#xff0c;每个部分称为一个单词。出于减少分析量的目的&#xff0c;我们希望划分出的单词数越少越好。你就是来完成这一划分工作的。输入第一行&#xff0c;一…

C语言学习笔记——文件

目录1 文件的概念2 程序文件和数据文件3 二进制文件和文本文件4 流4.1 流的概念4.2 标准流5 文件信息区和文件指针6 处理文件的库函数6.1 fopen6.2 fclose6.3 fgetc6.4 fputc6.5 fgets6.6 fputs6.7 fscanf6.8 fprintf6.9 fread6.10 fwrite6.11 fseek6.12 ftell6.13 rewind6.14 …

C++语法与面向对象特性(2)

一.inline函数1.inline的基本特性被inline修饰的函数被称为内联函数。inline函数设计的初衷是为了优化宏的功能&#xff0c;编译器会在编译阶段对inline函数进行展开。然而需要注意的是&#xff0c;inline对于编译器而言是一种建议&#xff0c;它通常会展开一些简短的&#xff…

Linux中grep命令

Linux 中的 grep 用法详解grep 是 Linux 中强大的文本搜索工具&#xff0c;用于在文件或输入流中查找匹配指定模式的行。其基本语法为&#xff1a;grep [选项] "模式" [文件]核心功能基础搜索在文件中查找包含特定字符串的行&#xff1a;grep "error" log.…

【遥感图像入门】遥感中的“景”是什么意思?

在遥感成像中,“3景城市影像”和“5景城市影像”中的“景”是遥感数据的基本单位,通常指一次成像过程中获取的独立遥感影像块。这一概念的具体含义需结合技术背景和应用场景理解: 一、“景”的技术定义 单次成像的独立覆盖区域 遥感平台(如卫星、飞机)在特定时间和位置对…

Pytorch-07 如何快速把已经有的视觉模型权重扒拉过来为己所用

下载&#xff0c;保存&#xff0c;加载&#xff0c;使用模型权重 在这一节里面我们会过一遍对模型权重的常用操作&#xff0c;比如&#xff1a; 如何下载常用模型的预训练权重如何下载常用模型的无训练权重&#xff08;只下载网络结构&#xff09;如何加载模型权重如何保存权…

C语言零基础第9讲:指针基础

目录 1.内存和地址 2.指针变量和地址 2.1 取地址操作符&#xff08;&&#xff09; 2.2 指针变量 2.3 解引用操作符&#xff08;*&#xff09; 2.4 指针变量的大小 3.指针变量类型的意义 3.1 指针的解引用 3.2 指针 - 整数 3.3 void*指针 4.指针运算 4.1 指针…

013 HTTP篇

3.1 HTTP常见面试题 1、HTTP基本概念&#xff1a; 超文本传输协议&#xff1a;在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」HTTP常见的状态码 [[Pasted image 20250705140705.png]]HTTP常见字段 Host 字段&#xff1a;客户…

每日面试题20:spring和spring boot的区别

我曾经写过一道面试题&#xff0c;题目是为什么springboot项目可以直接打包给别人运行&#xff1f;其实这涉及到的就是springboot的特点。今天来简单了解一下springboot和spring的区别&#xff0c; Spring 与 Spring Boot&#xff1a;从“全能框架”到“开箱即用”的进化之路 …