栈和队列的实现(Java篇)

news2024/11/22 17:59:54

文章目录

  • 一、栈的概念
  • 二、栈的实现
    • 2.1压栈(push)
    • 2.2出栈(pop)
    • 2.3获取栈顶元素(peek)
    • 2.4判断栈是否为空(isEmpty)
    • 栈的实现测试
  • 三、队列的概念
  • 四、队列的实现
    • 4.1入队(offer)
    • 4.2出队(poll)
    • 4.3判断队列是否为空
    • 4.4获取对头元素
    • 队列的实现测试
  • 五、循环队列
    • 5.1入队
    • 5.2出队
    • 5.3获取队头元素
    • 5.4获取队尾元素
    • 5.5判断队列是否为空
  • 六、双端队列


一、栈的概念

栈: 一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/0ec49aeaa26743fab2a2686fab1ac2d8.png
出栈:栈的删除操作叫做出栈。出数据在栈顶
在这里插入图片描述

二、栈的实现

栈是一个特殊的顺序表,所以采用链表和数组的方式都可实现,但是,一般采用数组的方式实现

创建一个类:

	public class MyStack {
	//创建一个数组
    public int[] elem;
    //存放的元素个数
    public int usedSize;
    //默认的容量
    public static final int DEFAULT_CAPACITY = 5;
    public MyStack() {
        this.elem = new int[DEFAULT_CAPACITY];
    }
}    

2.1压栈(push)

在入栈之前我们要判断栈是否满了,如果满了就要进行扩容

public boolean isFull() {
    return usedSize == elem.length;
}    
public void push(int val) {
    //判断
    if(isFull()) {
        elem = Arrays.copyOf(elem,2*elem.length);
    }
    elem[usedSize] = val;
    usedSize++;
}  

2.2出栈(pop)

同样在出栈的时候我们也要判断栈是否为空,为空就抛一个异常

public int pop() {
    //判断
    if(isEmpty()) {
        throw new EmptyStackException("栈为空");
    }
    int ret = elem[usedSize-1];
    usedSize--;
    return ret;
}    

2.3获取栈顶元素(peek)

在获取栈顶元素时也要判断栈是否为空

public int peek() {
    //判断
    if (isEmpty()) {
        throw new EmptyStackException("栈为空");
    }
    return elem[usedSize-1];
}    

2.4判断栈是否为空(isEmpty)

public boolean isEmpty() {
    return usedSize == 0;
}    

栈的实现测试

public class Test {
    public static void main(String[] args) {
        MyStack myStack = new MyStack();
        myStack.push(12);
        myStack.push(23);
        myStack.push(34);
        myStack.push(45);//压栈
        int ret = myStack.pop();//出栈
        System.out.println(ret);
        System.out.println("*****");
        int num = myStack.peek();//获取栈顶元素
        System.out.println(num);
        System.out.println("*****");
        System.out.println(myStack.isEmpty());//判断栈是否为空
    }
}

在这里插入图片描述

三、队列的概念

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾(Tail/Rear) 出队列:进行删除操作的一端称为队头(Head/Front)
在这里插入图片描述

四、队列的实现

要想实现一个队列,可以采用链表和数组两种存储数据的方式,那么到底应该用哪种方式实现
对于数组来说,入队列和出队列操作都相对简单,但是可能会造成空间大量浪费,那么我们就可以选择使用链表来实现

创建一个类:

public class MyQueue {
    static class ListNode{
        public int val;
        public ListNode prev;
        public ListNode next;
        public ListNode(int val) {
            this.val = val;
        }
    }
    public ListNode head;
    public ListNode last;
}

4.1入队(offer)

因为是链表所以在入队时不用考虑扩容的问题,代码执行时动态分配空间

public void offer(int val) {
    ListNode node = new ListNode(val);
    if(head == null) {
        head = last = node;
    }else {
    last.next = node;
    node.prev = last;
    last = node;
    }
}    

4.2出队(poll)

出队时要判断队头是否为空

public int poll() {
    //判断
    if(head == null) {
        return -1;
    }
    int val = -1;
    if(head.next == null) {
        val = head.val;
        head = null;
        last = null;
        return val;
    }
    val = head.val;
    head = head.next;
    head.prev = null;
    return val;
}    

4.3判断队列是否为空

 public boolean empty() {
     return head == null;
}    

4.4获取对头元素

public int peek() {
    if(head == null) {
        return -1;
    }
    return head.val;
}    

队列的实现测试

public class Test {
    public static void main(String[] args) {
        MyQueue queue = new MyQueue();
        queue.offer(12);
        queue.offer(23);
        queue.offer(34);
        queue.offer(45);//入队
        int ret = queue.poll();//出队
        System.out.println(ret);
        System.out.println("*****");
        System.out.println(queue.empty());//判断队列是否为空
        System.out.println("*****");
        int num = queue.peek();//获取队头元素
        System.out.println(num);
    }
}    

在这里插入图片描述

五、循环队列

实际中我们有时还会使用一种队列叫循环队列,循环队列通常使用数组实现。
利用数组实现一个队列可能会浪费大量的空间,那么,就可以使用循环队列,也能解决资源浪费的问题.
在这里插入图片描述
循环队列其本质也是一个数组
在这里插入图片描述
那我们如何区分空与满呢
1.通过添加 size 属性记录
2.保留一个位置
3.使用标记

这里我们使用第二种方式
在这里插入图片描述

5.1入队

因为是使用数组来实现的,所以在入队之前我们要判断队列是否满了

public boolean isFull() {
    return (rear+1)% elem.length == front;
}    

入队操作

public boolean enQueue(int value) {
    //判断
    if (isFull()) {
        elem = Arrays.copyOf(elem,2*elem.length);
    }
    elem[rear] = value;
    rear = (rear+1)%elem.length;
    return true;
}    

5.2出队

在进行出队操作时要判断队列是否为空

public boolean deQueue() {
    if (isEmpty()) {
        return false;
    }
    front = (front+1)%elem.length;
    return true;
}    

5.3获取队头元素

public int Front() {
    if (isEmpty()) {
        return -1;
    }
    return elem[front];
}    

5.4获取队尾元素

 public int Rear() {
     if (isEmpty()) {
         return -1;
     }
     return elem[rear];
}    

5.5判断队列是否为空

front和rear相遇了就为空

public boolean isEmpty() {
    return front == rear;
}    

六、双端队列

双端队列(deque)是指允许两端都可以进行入队和出队操作的队列,deque 是 “double ended queue” 的简称。
那就说明元素可以从队头出队和入队,也可以从队尾出队和入队
在这里插入图片描述
Deque是一个接口,使用时必须创建LinkedList的对象
Deque接口比较多,栈和队列都可以使用该接口

Deque<Integer> stack = new ArrayDeque<>();//双端队列的线性实现
Deque<Integer> queue = new LinkedList<>();//双端队列的链式实现

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

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

相关文章

手把手教你Linux查找Java的安装目录并设置环境变量以及Linux下执行javac未找到命令的保姆级教学

查找Java的安装目录 输入 java -version&#xff0c;查看是否成功安装Java 输入 which java&#xff0c;查看Java的执行路径 输入 ls -lrt /usr/bin/java 输入 ls -lrt /etc/alternatives/java&#xff0c;/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el7_7.x86_64 就是J…

系列七、函数

一、函数 1.1、概述 函数 是指一段可以直接被另一段程序调用的程序或代码。 也就意味着&#xff0c;这一段程序或代码MySQL中已经为我们提供好了&#xff0c;我们要做的就是在合适的业务场景调用对应的函数完成相应的业务需求即可。 1.2、分类 按照业务分类&#xff0c;MySQL中…

centOS安装bochsXshell连接centos启动可视化界面

centOS安装bochs 参考&#xff1a;https://blog.csdn.net/muzi_since/article/details/102559187 首先安装依赖环境&#xff1a; yum install gtk2 gtk2-devel yum install libXt libXt-devel yum install libXpm libXpm-devel yum install SDL SDL-devel yum install libXr…

【LeetCode刷题-哈希表】--187.重复的DNA序列

187.重复的DNA序列 本题就是找到长度为10的字符出现次数大于2的 子串序列 方法&#xff1a;使用哈希表 class Solution {public List<String> findRepeatedDnaSequences(String s) {List<String> ans new ArrayList<String>();HashMap<String,Integer&g…

【LeetCode刷题-字符串】-- 186.反转字符串中的单词II

186.反转字符串中的单词II 方法&#xff1a;先反转整个字符串再反转单词中的字母 class Solution {public void reverseWords(char[] s) {reverseCharacters(s,0,s.length-1);reverseEachWord(s);}//反转单词中的字母public void reverseEachWord(char[] s){int length s.len…

【CASS精品教程】cass11提示“请不要在虚拟机中运行此程序”的解决办法

文章目录 一、问题提示二、解决办法一、问题提示 按照正常安装教程安装好南方测绘cass 11之后,打开的时候可能会有以下提示:请不要在虚拟机中运行此程序,如下图所示: 遇到问题,咱们就想办法解决问题,下面将自己尝试的方法及最终解决情况跟大家说一下,供参考。 二、解决…

注册与回调

C 再谈谈注册(本质是建立映射)与回调 在之前的博文中&#xff0c; 我们探讨过映射的重要作用&#xff0c; 请直接看&#xff1a;http://blog.csdn.net/stpeace/article/details/39452203, 在那篇文章中&#xff0c; 我们是用STL中的map来做的&#xff0c; map建立的是key-value…

代码随想录算法训练营Day1 | 704.二分查找、27.移除元素

LeetCode 704 二分查找 题目链接&#xff1a;704.二分查找 本题思路&#xff1a;本题题目写的是二分查找&#xff0c;所以我们用到的算法肯定也是二分查找&#xff0c;需要定义 3个变量。 l: 从数组的下标0开始 r: 数组长度 - 1 mid&#xff1a;&#xff08;l r&#xff09;…

AUTOSAR组织引入了Rust语言的原因是什么?有哪些好处?与C++相比它有什么优点?并推荐一些入门学习Rust语言链接等

AUTOSAR(汽车开放系统架构)是一个由汽车制造商、供应商和其他来自电子、半导体和软件行业的公司组成的全球发展伙伴关系,自2003年以来一直致力于为汽车行业开发和引入开放、标准化的软件平台。 AUTOSAR 最近宣布成立一个新的工作组,用于探索在汽车软件中使用 Rust 编程语言…

【网络安全】网络防护之旅 - 点燃网络安全战场的数字签名烟火

​ &#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《网络安全之道 | 数字征程》⏰墨香寄清辞&#xff1a;千里传信如电光&#xff0c;密码奥妙似仙方。 挑战黑暗剑拔弩张&#xff0c;网络战场誓守长。 ​ 目录 &#x1f608;1. 初识…

2023年总结,讲讲我的故事吧,十年

文章目录 2023前十年后十年 周末&#xff0c;本该是提升自己的最好时机&#xff0c;也该是出去玩的大好时光&#xff0c;但是毫无意外的&#xff0c;在家躺了一天&#xff0c;单纯的有点累。 2023年&#xff0c;发生了好多事情&#xff0c;又好像没发生几件事&#xff0c;可能毕…

录制第一个jmeter性能测试脚本2(http协议)_图书管理系统

我们手工编写了一个测试计划&#xff0c;现在我们通过录制的方式来实现那个测试计划。也就是说‘’测试计划目标和上一节类似&#xff1a;让5个用户在2s内登录图书管理系统&#xff0c;然后进入 页面进行查看。 目录 欢迎访问我的免费课程 PPT、安装包、视频应有尽有&#xff…

Linux Shell——输入输出重定向

输入输出重定向 1. 重定向输入2. 重定向输出 总结 最近学习了shell语法&#xff0c;总结一下关于输入输出重定向的知识。 一般情况下&#xff0c;linux每次执行命令其实都会打开三个文件&#xff0c;分别是&#xff1a; 标准输入stdin 文件描述符为0 标准输出stdout 文件描述符…

mysql8支持远程访问

上面的localhost要改为%号就打开了远程访问 ALTER USER root% IDENTIFIED WITH mysql_native_password BY fengzi2141;

NSSCTF第16页(2)

[NSSRound#4 SWPU]1zweb(revenge) 查看index.php <?php class LoveNss{public $ljt;public $dky;public $cmd;public function __construct(){$this->ljt"ljt";$this->dky"dky";phpinfo();}public function __destruct(){if($this->ljt"…

Python将列表中的数据写入csv并正确解析出来

用Python做数据处理常常会将数据写到文件中进行保存&#xff0c;又或将保存在文件中的数据读出来进行使用。通过Python将列表中的数据写入到csv文件中很多人都会&#xff0c;可以通过Python直接写文件或借助pandas很方便的实现将列表中的数据写入到csv文件中&#xff0c;但是写…

C语言—小小圣诞树

这个代码会询问用户输入圣诞树的高度&#xff0c;然后根据输入的高度在控制台上显示相应高度的圣诞树。 #include <stdio.h>int main() {int height, spaces, stars;printf("请输入圣诞树的高度: ");scanf("%d", &height);spaces height - 1;st…

【MySQL】触发器trigger / 事件

文章目录 1. 触发器 trigger1.1 触发器命名1.2 new和old关键字1.3 案例&#xff1a;insert 触发器1.4 练习&#xff1a;delete 触发器1.5 查看触发器 show triggers1.6 使用触发器记录对表的操作 2 事件2.1 打开 / 关闭事件调度器2.2 创建事件 create event2.3 查看&#xff0c…

idea__SpringBoot微服务11——整合Druid数据源(新依赖)(新注解)

整合JDBC 一、导入依赖二、配置Druid————————创作不易&#xff0c;如觉不错&#xff0c;随手点赞&#xff0c;关注&#xff0c;收藏(*&#xffe3;︶&#xffe3;)&#xff0c;谢谢~~ 接着 第10的 新注解&#xff1a; ConfigurationProperties ConfigurationPropert…

流量分析基础

定义&#xff1a; 流量分析&#xff08;Traffic Analysis&#xff09;是指对网络流量数据进行分析和解释&#xff0c;以获得有关网络中通信的信息和情报。这种技术可以用于网络安全、网络管理和网络优化等领域。 网络流量包含了许多有关网络通信的细节信息&#xff0c;如源IP地…