数据结构_栈和队列

news2024/11/23 1:18:14

目录

一、栈

1.1 栈的使用

1.2 模拟实现栈

二、队列

2.1 队列的使用

2.2 环形队列

2.3 双端队列

总结


一、栈

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

入栈:栈的插入操作称为入栈/进栈/压栈,入数据在栈顶

出栈:栈的删除操作称为出栈,出数据在栈顶

1.1 栈的使用

在 Java 中,提供了 Stack 类来表示栈。

【栈方法】

方法功能
E push(E e)将 e 入栈,并返回
E pop()将栈顶元素出栈,并返回
E peek()获取栈顶元素
int size()获取栈中有效元素个数
boolean empty()判断栈中是否为空

1.2 模拟实现栈

首先定义定义数组来实现栈、usedSize 记录栈中有效元素个数、并定义其默认容量及其构造方法。

    //数组实现栈
    private int[] array;
    //栈中有效元素个数
    private int usedSize = 0;
    //栈默认容量
    private static final int DEFAULT_CAPACITY = 10;

    public MyStack() {
        array = new int[DEFAULT_CAPACITY];
    }

1、push():入栈

    public void push(int e) {
        //若栈已满,则扩容
        if (full()) {
            array = Arrays.copyOf(array, 2*array.length);
        }
        //usedSize标记着栈中元素个数的同时,
        //由于下标从 0 开始计数,元素个数从 1 开始计数
        //所以 usedSize 可以视为栈顶元素下标 +1
        array[usedSize] = e;

        usedSize++;
    }
    //是否已满
    public boolean full() {
        return usedSize == array.length;
    }

 usedSize 做当前可存放元素的下标:

2、pop():栈顶元素出栈,并返回

    public int pop() {
        //若栈为空,则抛异常
        if (empty()) {
            throw new EmptyException("栈为空!");
        }
        //创建变量接收原栈顶元素
        int old = array[usedSize-1];

        //栈顶元素被获取
        usedSize--;

        //返回原栈顶元素
        return old;
    }

3、peek():获取栈顶元素 

    public int peek() {
        //栈中有效个数为 0,抛异常
        if (usedSize == 0) {
            throw new EmptyException("栈为空!");
        }
        //返回栈顶元素
        return array[usedSize-1];
    }

4、size():获取栈中有效元素个数

    public int size() {
        //返回栈中有效元素个数
        return usedSize;
    }

5、empty():判断栈是否为空

    public boolean empty() {
        //若栈中有效个数为 0,则返回 true;反之 false
        return usedSize == 0;
    }


二、队列

队列是只允许在一端进行插入数据操作,在另一端进行删除数据操作的一种特殊线性表。队列遵循先进先出原则。

入队列:进行插入操作的一端称为队尾

出队列:进行删除操作的一端称为队头

2.1 队列的使用

在 Java 中,提供了 Queue 接口来表示队列,其底层是通过链表实现的。由于 Queue 是一个接口,所以实例化队列时必须实例化 LinkedList 对象,因为 LinkedList 实现了 Queue 接口。

【队列方法】

方法功能
boolean offer(E e)入队列
E poll()出队列
E peek()获取队头元素
int size()获取队列内有效元素个数
boolean isEmpty()判断队列内是否为空
import java.util.LinkedList;
import java.util.Queue;

public class QueueDemo {
    public static void main(String[] args) {
        //创建一个空队列
        Queue<Integer> queue = new LinkedList<>();

        //入队列
        queue.offer(11);
        queue.offer(22);
        queue.offer(33);

        //获取队头元素
        System.out.println(queue.peek()); //11

        //获取队列中有效元素个数
        System.out.println(queue.size()); //3

        //出队列:先进先出
        queue.poll(); //11最先进入,故 11出队列

        //再次获取队头元素
        System.out.println(queue.peek()); //22

        System.out.println(queue.size()); //2

        //判断队列是否为空
        System.out.println(queue.isEmpty()); //false
    }
}

2.2 环形队列

环形队列还可以叫做循环队列,顾名思义,即当队列存放元素至队列尾后,此时可存放元素的下标再次循环至队列头,其通常使用数组实现。在生产者消费者模型中,就可以使用循环队列。

在实现环形队列之前,我们先定义变量 front 与 rear,front 表示队列头,rear 表示当前可以存放元素的下标。

此时就需要解决 rear 与 front 相遇时队列为空还是为满的问题,这里我们采用浪费一个空间来判断队列是否已满,即当 rear 的下一个就是 front 时,此时认为队列已满,需等 front 下标元素出队,才可再次存放元素。

同时,还需解决 rear 怎么从 5 下标前往 0 下标的问题,我们可以使用 (rear+1) % length 来决定当前存放元素的下标。

class MyCircularQueue {

    public int[] array; //定义数组实现环形队列
    public int front = 0; //队头,初始为 0
    public int rear = 0; //当前存放元素的下标,初始为 0

    public MyCircularQueue(int size) {
        array = new int[size];
    }

    //入队
    public boolean inQueue(int value) {
        //若队列已满,则 false
        if (isFull()) {
            return false;
        }
        //存入元素
        array[rear] = value;
        //为防止前往 0 下标时出错,故不用 rear++
        rear = (rear+1) % array.length;

        return true;
    }

    //出队
    public boolean outQueue() {
        //若队列为空,则 false
        if (isEmpty()) {
            return false;
        }
        //与 rear 同理,防止前往 0 下标时出错
        front = (front+1) % array.length;

        return true;
    }

    //获取队头元素
    public int Front() {
        //若队列为空,则 -1
        if (isEmpty()) {
            return -1;
        }
        //返回 front 下标元素
        return array[front];
    }

    //获取队尾元素
    public int Rear() {
        //若队列为空,则 -1
        if (isEmpty()) {
            return -1;
        }
        //队尾元素是处于 rear 下标的前一个,
        //若 rear 下标为 0,则队尾元素在队列最大下标处;
        //其余情况,队尾元素处于 rear-1 下标处。
        int tail = rear == 0 ? array.length-1 : rear-1;
        return array[tail];
    }
    
    //判断队列是否为空
    public boolean isEmpty() {
        //若 front 与 rear 相等,则队列为空
        return front == rear;
    }
    
    //判断队列是否已满
    public boolean isFull() {
        //若 rear 的下一个是 front,则队列已满
        return (rear+1) % array.length == front;
    }
}

2.3 双端队列

双端队列是指在队列两端都可以进行入队和出队的操作。Java 中提供 Deque 接口来表示双端队列。

【栈和队列均可使用 Deque 接口】

1、双端队列的线性实现:Deque<Integer> stack = new ArrayDeque<>();

2、双端队列的链式实现:Deque<Integer> queue = new LinkedList<>();


总结

1、栈遵循先进后出 (后进先出) 原则,队列遵循先进先出原则。

2、栈只允许在固定的一端进行元素的插入和删除操作。

3、队列只允许在一端进行插入数据操作,在另一端进行删除数据操作。

4、栈和队列均可使用 Deque 接口。 

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

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

相关文章

MQTT服务器/MQTT_C#客户端/Websoket连MQTT

1 . 搭建MQTT服务器 找到上传中的 emqx-5.3.2-windows-amd64 打开bin如下: 链接: emqx-5.3.2-windows-amd64 如果安装失败 在上传中找到链接: VC_redist.x64.exe 安装。 正确后在浏览器输入 http://127.0.0.1:18083 会有如下mqtt服务端管理页面: 进入客户端认证,创建一个…

72. UE5 RPG 实现召唤技能数量的限制,并优化技能相关

在上一篇文章里&#xff0c;我们实现了召唤技能&#xff0c;并且能够无限的召唤。所以&#xff0c;这属于一个bug&#xff0c;我们不能无限制的去召唤&#xff0c;这会影响游戏的体验。所以&#xff0c;在这篇里面&#xff0c;我们实现一下对召唤物数量的限制&#xff0c;并优化…

32.双击列表启动目标游戏

上一个内容&#xff1a;31.加载配置文件中的游戏到辅助列表 以 31.加载配置文件中的游戏到辅助列表 它的代码为基础进行修改 效果图&#xff1a; 添加列表双击事件 实现代码&#xff1a; LPNMITEMACTIVATE pNMItemActivate reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR…

掌控浮动布局,主宰页面之美

浮动有很多的效果 实现文字环绕效果导致一个元素脱离文档流可以让块级元素水平排列浮动元素可以用 marign, 但是不能使用 margin: 0 auto; 同时也会带来很多不好的效果 如果我想要让文字在图片的旁边应该怎么做&#xff1f; 这里我们就可以使用浮动float: left;去实现 <…

Java | Leetcode Java题解之第168题Excel表列名称

题目&#xff1a; 题解&#xff1a; class Solution {public String convertToTitle(int columnNumber) {StringBuffer sb new StringBuffer();while (columnNumber ! 0) {columnNumber--;sb.append((char)(columnNumber % 26 A));columnNumber / 26;}return sb.reverse().t…

【odoo | JSON-RPC】无会话(session_id)控制的api,外部api密钥的另一种表现!

概要 在Odoo中&#xff0c;JSON-RPC&#xff08;JSON Remote Procedure Call&#xff09;是一种基于JSON格式的远程过程调用协议&#xff0c;用于客户端和服务器之间的通信。此文章将介绍 JSON-RPC中无会话(session_id)控制的api&#xff0c;也是外部api密钥的另一种表现方式。…

【Linux基础IO】重定向以及原理分析

我们先来看下面一个情况&#xff1a; #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define filename "text.txt"int main(){close(1);//关…

差分数组汇总

本文涉及知识点 算法与数据结构汇总 差分数组 令 a[i] ∑ j : 0 i v D i f f [ i ] \sum_{j:0}^{i}vDiff[i] ∑j:0i​vDiff[i] 如果 vDiff[i1]&#xff0c;则a[i1…]全部 如果vDiff[i2]–,则a[i2…]全部–。 令11 < i2 &#xff0c;则&#xff1a; { a [ i ] 不变&…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 身高差值排序(100分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; &#x1f…

重学java 77.JDK新特性 ③ Stream流

The road is long,it can be really hard.Whatever you do,you hold on to that foolishly hopeful smile —— 24.6.19 Stream流 stream流中的"流"不是特指"IO流",它是一种"流式编程"(编程方式),可以看做是"流水线 package S109Stream;im…

在 Visual Studio 2022 (Visual C++ 17) 中使用 Visual Leak Detector

在 Visual C 2022 中使用 Visual Leak Detector 1 问题描述1.1 内存泄漏的困扰和解决之道1.2 内存泄漏检测工具的选择1.3 VLD的现状 2 安装和设置VLD的环境变量2.1 安装VLD文件2.2 VLD安装后的目录和文件说明2.2.1 include子目录说明2.2.2 lib子目录说明2.2.2.1 目录整理 2.2.3…

【全文档】软件项目经理需要掌握的文档有哪些?

软件项目经理在项目管理过程中需要编写多种文档&#xff0c;以下是常见的十五个文档&#xff1a; 项目计划&#xff1a; 详细描述了项目的范围、时间、成本、资源、沟通计划等关键信息&#xff0c;是项目管理的核心文档。 需求文档&#xff1a; 记录了项目的业务需求、功能需求…

VMR,支持30+种编程语言的SDK版本管理器,支持Windows/MacOS/Linux。

官方文档地址&#xff1a;documents 官方项目地址&#xff1a;github 欢迎安装使用&#xff0c;分享转发&#xff0c;前往github star。 跨平台&#xff0c;支持Windows&#xff0c;Linux&#xff0c;MacOS支持多种语言和工具&#xff0c;省心受到lazygit的启发&#xff0c;拥…

【stm32-新建工程-CubeMX】

stm32-新建工程-CubeMX ■ CubeMX 生产工程 ■ CubeMX 生产工程

数据库 |试卷八试卷九试卷十

1.基数是指元组的个数 2.游标机制 3.触发器自动调用 4.count(*)统计所有行&#xff0c;不忽略空值null&#xff0c;但不但要全局扫描&#xff0c;也要对表的每个字段进行扫描&#xff1b; 5.eacherNO INT NOT NULL UNIQUE&#xff0c;为什么不能断定TeacherNO是主码&#xff…

JAVAEE之网络原理(2)_传输控制协议(TCP)的连接管理机制,三次握手、四次挥手,及常见面试题

前言 在上一节中&#xff0c;我们简单介绍了 TCP 协议的相关概念和格式&#xff0c;而且还介绍了TCP 协议原理中的 确认应答机制、超时重传机制&#xff0c;在本节中我们将会继续介绍 TCP协议原理中的其他机制。 连接管理机制&#xff08;安全机制&#xff09; 在正常情况下&…

数学建模基础:统计模型

目录 前言 一、概率与统计基础 二、统计模型 三、Matlab统计工具箱 四、实例示范&#xff1a;市场调查分析 步骤 1&#xff1a;数据导入 步骤 2&#xff1a;数据可视化 步骤 3&#xff1a;建立多元线性回归模型 步骤 4&#xff1a;模型验证 步骤 5&#xff1a;模型应…

Java学习 (二)关键字、标识符、数组

一、关键字 我们第一章案例中有很多关键字&#xff0c;比如class、public、static、void等&#xff0c;这些关键字依旧被java定义好了&#xff0c;可以拿来用&#xff0c;不需要死记硬背&#xff0c;按照官方文档查询即可 #官方文档 https://docs.oracle.com/javase/tutorial/j…

高速公路收费图片分析系统深入理解

当今社会&#xff0c;随着交通运输业的快速发展&#xff0c;高速公路已成为人们出行的重要选择。而高速公路收费系统作为保障道路可持续运营的重要组成部分&#xff0c;其效率和准确性对于保障道路畅通和交通安全至关重要。近年来&#xff0c;随着技术的不断进步&#xff0c;高…

elasticsearch的安装和配置

单节点安装与部署 我们通过docker进行安装 1.docker的安装 如果以及安装了docker就可以跳过这个步骤。 首先更新yum: yum update安装docker: yum install docker查看docker的版本&#xff1a; docker -v此时我们的docker就安装成功了。 2.创建网络 我们还需要部署kiban…