【数据结构趣味多】栈和队列(详细解析)

news2024/11/18 23:58:49

目录

1.1 栈的定义 

 1.2 栈的模拟实现(顺序栈)

push()方法

pop()方法

peek()方法

size()方法

栈模拟实现的全代码

1.3顺序栈和链栈的对比

2.队列

2.1队列的定义

2.1队列的模拟实现(单链表)

offer()函数

poll()函数

peek()函数

size()函数

isEmpty()函数

队列实现的全代码 

 总结


1.1 栈的定义 

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

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据在栈顶。

 栈分为顺序栈和链栈,我们先研究顺序栈,链栈等以后再说。

 下方是栈继承的类,以及栈实现的接口。

 1.2 栈的模拟实现(顺序栈)

栈一共包含6个方法,我们模拟实现中所有数据类型都用int类型代替

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

push()方法

作用:此方法是让元素入栈。
实现原理:首先判断线性表是否已满,如果线性表已满,就需要扩容。之后就是将数据放入线性表,并将栈大小加一。

public void push(int val) {
        if(stack.length==stackSize) {
            stack=Arrays.copyOf(stack,2*stackSize);
        }
        stack[stackSize++]=val;
    }

pop()方法

作用: 此方法是让栈顶元素出栈。

实现原理:出栈的前提一直到栈中有元素;因此,我们先判断栈是否胃口,若为空栈,就抛出异常,让程序停下来,若不为空栈,就弹出栈底元素,并将栈大小减一。

public int pop() {
        if(empty()) {
            throw new RuntimeException("空栈!");
        }
        return  stack[--stackSize];
    }

peek()方法

作用: 如他的名字一样,peek 偷看,看一眼栈顶的元素,但不出栈。

实现原理:判断栈是否为空,若是空栈不能偷看到元素,抛异常停止运行;若不为空栈返回栈底元素即可。

public int peek() {
        if(empty()) {
            throw new RuntimeException("空栈!");
        }
        return  stack[stackSize-1];
    }

size()方法

作用: 得到栈中有多少个元素

实现原理:直接返回成员变量stackSize

栈模拟实现的全代码:

import java.util.Arrays;

public class MyStack {
    private int[]  stack;
    private int stackSize;
    public MyStack() {

        this.stack=new int[3];
    }
    public void push(int val) {
        if(stack.length==stackSize) {
            stack=Arrays.copyOf(stack,2*stackSize);
        }
        stack[stackSize++]=val;
    }
    public int pop() {
        if(empty()) {
            throw new RuntimeException("空栈!");
        }
        return  stack[--stackSize];
    }
    public int peek() {
        if(empty()) {
            throw new RuntimeException("空栈!");
        }
        return  stack[stackSize-1];
    }
    public int size() {
        return stackSize;
    }
    public  boolean empty() {
        if(stackSize==0) {
            return true;
        }
        return  false;
    }
}

1.3顺序栈和链栈的对比

        栈有链栈顺序栈之分,上方是用顺序表实现的名叫顺序栈;我们还可以使用链表实现,对于用链表实现栈,会很好实现,因为我们不需要考虑栈满的情况,若链栈满了,那可以说是你的计算机操作系统就面临崩溃。 

 时间复杂度:链栈和顺序栈,它们在时间复杂度上都是O(1)。

 空间复杂度:顺序栈需要事先确定一个长度,可能会造成内存空间的浪费,但是优势是存取时定位方便;链栈每个元素都要有一个指针域,增加了内存的开销,但长度无限。

两者如何选择:如果栈的使用过程中元素变化不可预知,最好用链栈;若变化在可控范围内,使用顺序栈更好。

 关于栈的练习题我也做了总结:

【代码题】栈的应用https://blog.csdn.net/qq_65228171/article/details/128581622?spm=1001.2014.3001.5501

2.队列

2.1队列的定义

队列: 只允许在一端进行插入操作,而在另一端进行删除操作的线性表,允许插入的一端称为队尾,允许删除的一端称为对头。一种先进先出的线性表。

队列实现的接口:

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

2.1队列的模拟实现(单链表)

 队列一共有5种方法

方法功能
boolean offer(E e)入队列
E poll()出队列
peek()获取队头元素
int size()获取队列中有效元素个数
boolean isEmpty()检测队列是否为空

offer()函数

作用:将新元素入队,位置是单链表尾部。

实现原理:将给给定的数值new一个新节点,如果头节点为空,就让头结点和尾节点都等于noed,如果不为空,就使用尾插法将node插到链表尾部。

//入队
    public void offer(int val) {
        Node node=new Node(val);
        if(head==null) {
            head=node;
            last=node;
        }else {
            last.next=node;
            last=last.next;
        }
        usedSize++;
    }

poll()函数

作用:将队头元素出队,位置单链表头指针所指元素。

实现原理:首先判断链表是否为空,若空,抛出异常;若不空,出头指针指的元素,并将使用大小减一。

 //出队
    public int poll() {
        if(isEmpty()) {
            throw new RuntimeException("队列空");
        }
        int tmp=head.val;
        head=head.next;
        usedSize--;
        return val;
    }

peek()函数

作用:偷看一下队头元素,不出队

实现原理:将首先判断队列是否空,若空,抛出异常;若不为空,返回头节点所指数值。

public int peek() {
        if(isEmpty()) {
            throw new RuntimeException("队列空");
        }
        int tmp=head.val;
        return val;
    }

size()函数

作用:返回有多少个元素

实现原理:直接返回成员变量usedSize

public int size() {
        return usedSize;
    }

isEmpty()函数

作用:将判断队列是否空。

实现原理:如果头节点是空,证明没有元素入队。

//判断空队列
    public boolean isEmpty() {
        if(usedSize==0) {
            return true;
        }
        return false;
    }

队列实现的全代码 

public class MyQueue {
    private int val;
    private  int usedSize;
    static class Node {
        public int val;
        public Node next;

        public Node(int val) {
            this.val = val;
        }
    }

    private Node head;
    private Node last;

    //入队
    public void offer(int val) {
        Node node=new Node(val);
        if(head==null) {
            head=node;
            last=node;
        }else {
            last.next=node;
            last=last.next;
        }
        usedSize++;
    }

    //出队
    public int poll() {
        if(isEmpty()) {
            throw new RuntimeException("队列空");
        }
        int tmp=head.val;
        head=head.next;
        usedSize--;
        return val;
    }

    //看队头
    public int peek() {
        if(isEmpty()) {
            throw new RuntimeException("队列空");
        }
        int tmp=head.val;
        return val;
    }

    //判断空队列
    public boolean isEmpty() {
        if(usedSize==0) {
            return true;
        }
        return false;
    }
    
    public int getUsedSize() {
        return usedSize;
    }
}

 总结

  1. 栈和队列,他们都是特殊的线性表,只不过在删除和插入操作上做了限制。
  2. 栈(stack)是限制仅在表尾进行插入和删除操作的线性表。
  3. 队列(queue)是限制只允许一端进行插入操作,另一端进行删除操作的线性表。

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

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

相关文章

ABB AC500 PLC 与西门子 S7-300 CPU DP 通讯

硬件连接 将一个 AC500 CPU(本例 PM583) 左侧插入以 DP 通讯扩展模块 CM572,使用 DP 通讯电缆连接 CM572 与 314-2DP CPU 的 DP 通讯口。连接示意图如下: AC500 DP 主站配置 安装 DP 从站设备描述文件 从西门子官方网站下载 CP…

认识二叉树

hi,代噶候。今天带大家认识一下二叉树,这个二叉树在我看来确实很有难度,但是不要怕,,鲁迅先生曾经说过,真正的勇士敢于面对惨淡的人生,敢于正视淋漓 的鲜血,下面让我们开始吧&#x…

线程池的内部结构与原理解析

线程池的内部结构 使⽤线程池的原因: 1、降低资源消耗 2、控制并发的数量。并发数量过多,可能会导致资源消耗过多,从⽽造成服务器崩溃 3、提高线程的可管理性 1、线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源&…

Global Illumination_SDF Generate Visualize Shadow

Signed Distance Field(有向距离场),简称SDF,这其实是图形学中非常常用的数学概念。数学上来说,是定义在空间中的一个标量场,标量值为空间一点到曲面的距离。曲面外的点为正值,曲面上的点为0,曲面内的点为负…

通用vue组件化展示列表数据

一、数据的简单展示 1.首先先确定要展示的表格列名以及拿到所需要展示的数组数据 2.然后建立一个专门放el-table遍历的文件 3.在父组件中将数据列表数据存放在listData里面,然后传给子组件,子组件定义一个动态的列,通过遍历propList得到列名…

SpringCloud从入门到精通(八)

config config-概述 • Spring Cloud Config 解决了在分布式场景下多环境配置文件的管理和维护。 • 好处: 集中管理配置文件 不同环境不同配置,动态化的配置更新 配置信息改变时,不需要重启即可更新配置信息到服务config-快速入门 gitee搭…

一文告别结合Nacos后,Springboot的配置文件看不懂的痛苦

一、背景 后端基于SpringCloud项目架构的话,默认会使用Nacos来做配置中心,但是这对从来没接触过Nacos配置中心的小伙伴,肯定就不知道怎么回事了,于是便有了这一篇指引。 二、Nacos配置中心是如何引入SpringCloud项目中的呢&…

操作系统实验8:proc文件的实现

实验目的 掌握虚拟文件系统的实现原理实践文件、目录、索引节点等概念 实验内容 在Linux 0.11上实现procfs(proc文件系统)内的psinfo结点。当读取此结点的内容时,可得到系统当前所有进程的状态信息。例如,用cat命令显示/proc/p…

有限状态机

文章目录1.概念2.什么是计算3.什么是有限状态机3.1特性3.2为什么要用状态机4.实战4.1字符串转换整数4.2用有限状态机实现4.3源码1.概念 有限状态机(英语:finite-state machine,缩写:FSM)又称有限状态自动机&#xff0…

【手写 Vue2.x 源码】第十篇 - 数组数据变化的观测情况

一,前言 上篇,主要介绍了对象数据变化的观测情况,涉及以下几个点: 实现了对象老属性值变更为对象、数组时的深层观测处理; 结合实现原理,说明了对象新增属性不能被观测的原因,及如何实现数据…

综合案例二 旅游网【1.项目导入技术选型注册表单校验登录退出表单】注册表空指针异常和其他一些错误

目录 前提:项目导入 在maven中点击travel项目(这里我是将项目添加到hello_maven里 ) 1.启动项目 方式一:maven命令启动 方式二:配置maven快捷启动 2.技术选型 1 Web层 2 Service层 3 Dao层 3.创建数据库…

56/14 shell脚本 后台启动 程序1 + “tail -f log“, ctrl +c 导致程序1中断

前言 接上一篇文章, node 程序后台执行加上 tail 命令, 中断 tail 命令, 同时也中断了 node 程序 我们来详细 参照对比一下 这个问题的各种情况 主要的脚本如下类似, 第一条命令 后台启动 程序1, 然后 第二条命令 tail -f 查看日志 然后 ctrlc 中断 "tail -f" …

实现自己的打印函数

文章目录前言前置知识代码说明实验操作单字符打印字符串打印整形字符串打印前言 本博客记录《操作系统真象还原》第六章实验的操作~ 实验环境:ubuntu18.04VMware , Bochs下载安装 实验内容: 实现 put_char 单字符打印输出函数。实现 put_…

TEE 背景知识

TEE 背景 计算机世界的安全,是保护计算机系统和网络免受攻击者的攻击,这些攻击可能导致未经授权的信息泄露、窃取或损坏硬件、软件或数据,以及它们所提供的服务的中断或误导。更多参考 Computer_security 1 安全是什么 谈安全,…

28.0:Combit LIST LABEL Reporting for Delphi Crack

作为 Delphi 开发人员的优势: 将 VCL 组件直接集成到 Embarcadero IDE 中 免版税报表设计器 交互式预览等 使用综合报表对象 Delphi 和所有其他相关语言和开发环境的报告工具。 将列表和标签集成到 Embarcadero RAD Studio List & Label 的 VCL 组件编译并直接…

HTML与CSS基础(八)—— CSS布局(定位、装饰、选择器拓展)

目标能够说出 定位 的常见应用场景 能够说出 不同定位方式 的特点 能够使用 子绝父相 完成元素水平垂直案例 能够写出三种常见的 光标类型(cursor) 能够使用 圆角边框 属性完成 正圆 和 胶囊按钮 效果 能够说出 display 和 visibility 让 元素本身隐藏 的…

【java查漏补缺】File类的使用

File类可以用来处理文件数据,比如使用list()方法可以获得某个文件夹下面的所有文件名。 File类的list()方法有一个含有一个参数的重载,在调用该方法的时候需要传入一个FilenameFilter对象,这样便可以进行文件名过滤。 我们先来看一下list()…

GJB 5000B二级-PP项目策划

一、主要变化情况 合并10项(绿色)、修订3项(蓝色)、删除1项(红色) 新增的主要内容 基于A版标准“项目策划”、“集成项目管理”、“定量项目管理”三个过程域中有关项目策划实践的内容来识别,没有新增实践,只增加了以下两个要求: 1、增加软件项目和设备/系统生存周…

Java线程之中断方法

interrupt()方法介绍interrupt() 给目标线程发送一个中断信号,同时将目标线程的中断标志设置为true。至于目标线程是否做出响应,需要看目标线程是否有对应的中断业务逻辑。场景1:假设,你是一个工厂的老板(main线程&…

C++类和对象(下)

目录 初始化列表 explicit关键字 Static成员 友元 友元函数 友元类 匿名对象 内部类 初始化列表 初始化列表是以冒号开始,以逗号分割的成员列表,每一个成员变量后面跟一个放在括号中的初始值或表达式。(代码演示以日期类为例&#xff…