关于栈的简单理解

news2024/9/24 17:08:38

1. 栈(Stack)

1.1 文字讲解

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

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

        出栈:栈的删除操作叫做出栈。出数据在栈顶。

1.2 图像分析

        从上图中可以看到,Stack继承了Vector父类,Vector和ArrayList类似,都是动态的顺序表,不同的是Vector是线程安全的。 

        下图图一和图二分别是入栈和出栈操作关于栈顶和栈底的图解:

2、自定义栈的实现 

2.1  栈的实现方法和功能表达

        详细方法和功能如下图:

2.2 自定义栈的代码实现

        说明:本栈的实现主要 采用int型数组的结构;

2.2.1 栈的创建

        思路:

        1、创建一个MyStack类,其中定义两个成员变量,数组(用来存放底层数据)和长度(用来记录当前的栈里面存放数据的数量),实现3中定义的接口,重写其方法让栈的操作具体化;

        2、构造方法,创建一个默认长度为10的数组;

public class MyStack implements IStack{
    private int[] data;
    private int usedLength;//实际已经占用的数组长度

    private static final int Default_Length = 10;

    public MyStack() {
        this.data = new int[Default_Length];
    }


    @Override
    public void push(int x) {

    }

    @Override
    public int pop() {
        return 0;
    }

    @Override
    public int peek() {
        return 0;
    }

    @Override
    public int size() {
        return 0;
    }

    @Override
    public boolean empty() {
        return false;
    }

    @Override
    public boolean full() {
        return false;
    }
}

        3、定义一个接口,在里面创建栈一系列操作的抽象方法;

public interface IStack {
    void push(int x);
    int pop();
    int peek();
    int size();
    boolean empty();
    boolean full();
}

2.2.2 压栈方法的实现

        1、首先对当前栈进行判断是否为满,若满则需要对当前栈进行二倍容量扩容

        2、当栈的容量充足时,在栈顶进行入栈(底层数组尾部进行添加数据)

        3、当前栈的数量长度加一;

@Override
    public void push(int x) {
        if (full() == true){
            this.data = Arrays.copyOf(data,2*Default_Length);
        }
        data[usedLength] = x;
        usedLength++;
    }

    @Override
    public boolean full() {
        if (usedLength == data.length){
            return true;
        }
        return false;
    }

 2.2.3 栈是否为空操作

 @Override
    public boolean empty() {
        return usedLength == 0;
    }

2.2.4出栈的实现

       思路:

         1、首先得判断当前栈栈是否为空,若为空我们需要抛出栈为空自定义异常(自定义一个异常为EmptyException);

public class EmptyException extends RuntimeException{
    public EmptyException(String msg) {
        super(msg);
    }
}

        2、将当前的栈顶的元素存储到容器中并返回

        3、将栈的长度加一,之前栈顶的数据引用地址就会变成null(空指针),出栈的数据的地址就不会被引用而导致数据从栈里消失;

        图解如下:

        代码如下:

 @Override
    public int pop() {
       if (empty()){
           throw new EmptyException("当前这个栈是空的!!!");
       }
 
        int old = data[usedLength-1];
        usedLength--;//相当于是删除
        return old;
    }

2.2.5获取栈中数据元素个数

@Override
    public int size() {
        return usedLength;
    }

2.2.6获取栈顶元素

        思路类似于2.2.4;

 @Override
    public int pop() {
       if (empty()){
           throw new EmptyException("当前这个栈是空的!!!");
       }
        int old = data[usedLength-1];
        usedLength--;//相当于是删除
        return old;
    }

3.关于链表的栈使用
3.1单链表

        从头部插入(入栈),从头部删除(出栈),时间复杂度为O(1);

         从尾部插入(入栈),从尾部删除(出栈),时间复杂度为O(n);不建议使用

3.2双向链表:

        从头部插入(入栈),从头部删除(出栈)

        从尾部插入(入栈),从尾部删除(出栈),有last引用,直接到表尾部        

        二者时间复杂度皆为O(1);

3.3 LinkedList自带实现方法:

 public static void main(String[] args) {
        LinkedList<Integer> linkedList = new LinkedList<>();
        linkedList.push(101);
        linkedList.push(102);
        linkedList.push(103);
        linkedList.push(104);
        System.out.println(linkedList.peek());
        System.out.println(linkedList.pop());
        System.out.println(linkedList.pop());
    }

        测试结果:

 

4.Q&A

Q1:栈、虚拟机栈、栈帧有什么区别呢?

A1:

        栈:是一种数据结构里面的概念,用来存放数据的一种模式;

        虚拟机栈:jvm虚拟机划分的一块内存;

        栈帧:调用方法的时候会在虚拟机中给这个方法开辟一个空间;

ps:本次内容就到这里了,如果喜欢的话就请一键三连哦!!!


 

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

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

相关文章

IP5316 2.4A 充电、2.4 A 放电、集成 DCP 功能移动电源 SOC

IP5316 2.4A 充电、 2.4 A 放电、集成 DCP 功能移动电源 SOC 简介&#xff1a; IP5316 是一款集成升压转换器、锂电池充电管理、电池电量指示的多功能电源管理 SOC&#xff0c;为移动电源提供完整的电源解决方案。得益于 IP5316 的高集成度与丰富功能&#xff0c;使其在应用时…

零信任组件和实施

零信任是一种安全标准&#xff0c;其功能遵循“从不信任&#xff0c;始终验证”的原则&#xff0c;并确保没有用户或设备受信任&#xff0c;无论他们是在组织网络内部还是外部。简而言之&#xff0c;零信任模型消除了信任组织安全边界内任何内容的概念&#xff0c;而是倡导严格…

外包干了2个月,技术明显退步了...

先说一下自己的情况&#xff0c;大专生&#xff0c;19年通过校招进入广州某软件公司&#xff0c;干了接近5年的功能测试&#xff0c;今年11月份&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测…

JS实现成才网注册系统(网页数据验证)

主代码 <!DOCTYPE htmlPUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.org/1999/xhtml"><head><meta http-equiv"Conten…

OpenGL ES 帧缓冲对象介绍和使用示例

一、介绍 1. 帧缓冲对象 默认情况下&#xff0c;OpenGL渲染的目标是屏幕&#xff0c;但如果你不想直接渲染到屏幕上&#xff0c;还需要对渲染结果做某些后期处理、渲染到纹理、阴影映射等操作&#xff0c;便可以使用帧缓冲对象&#xff0c;实现离屏渲染。 帧缓冲对象&#x…

DC电源模块的常见故障有哪些?

BOSHIDA DC电源模块的常见故障有哪些&#xff1f; DC电源模块是电子设备中常见的电源供应模块&#xff0c;它可以将交流电转化为直流电供给设备使用。然而&#xff0c;由于长期的使用和外界环境等因素的影响&#xff0c;DC电源模块也会出现各种故障。下面我们来介绍一下常见的…

【go语言开发】编写单元测试

本文主要介绍使用go语言编写单元测试用例&#xff0c;首先介绍如何编写单元测试&#xff0c;然后介绍基本命令的使用&#xff0c;最后给出demo示例 文章目录 前言命令示例 前言 在go语言中编写单元测试时&#xff0c;使用说明 测试文件命名&#xff1a;在 Go 语言中&#xff0…

蓝桥杯网络安全组竞赛

竞赛规则及说明 选拔赛时长&#xff1a;4h 决赛时长&#xff1a;4h 竞赛形式&#xff1a;线上比赛&#xff1a; 个人赛&#xff1a;一人一机&#xff0c;全程机考 大赛制定竞赛系统&#xff0c;在时间内提交答案到比赛系统&#xff0c;超时无法提交 机器环境&#xff1a; 电脑…

CSRF之pikachu靶场DW

1&#xff0c;登录皮卡丘靶场&#xff0c;get请求&#xff1b; 2&#xff0c;抓包并修改标记后的个人信息 最后放通一下&#xff0c;发现账号信息被修改 2&#xff0c;post请求 1提交post数据并使用bp抓包 2.利用工具改包&#xff0c;并生成url 3&#xff0c;点击提交后&#…

应用在触摸开关触控屏中的电容式触摸芯片

触摸开关是一种电子开关&#xff0c;使用时轻按开关按钮即可打开开关。松开手时&#xff0c;开关断开&#xff0c;内部结构由金属弹片受力弹动断开或者由电容值&#xff0c;电阻值等电气参数改变而控制。触摸开关一般是指应用触摸感应芯片原理设计的一种墙壁开关&#xff0c;是…

ArkUI组件--Button组件

1.声明Button组件 Button(label?:ResourceStr) #label是按钮上显示的文本 ①label是文字类型 所写文字会在按钮上显示 ②不输入label内容&#xff0c;需要额外定义一些描述。例如插入图片&#xff08;需要定义图片属性&#xff09; Button(){Image($r(app.media.xxx)).wi…

风靡万千软件开发者:揭秘华为研发代码大模型是如何实现的?

作者&#xff1a;陈泰红 秉持“自己的降落伞&#xff0c;自己先跳”的原则&#xff0c;由公司装备部门牵头&#xff0c;携手华为云PaaS作为基础能力提供方&#xff0c;与公司各产品线共同研发面向产业的代码大模型。在研发过程中&#xff0c;我们已取得初步成果&#xff0c;为…

LeetCode:1038. 从二叉搜索树到更大和树(反向中序遍历 C++、Java)

目录 1038. 从二叉搜索树到更大和树 题目描述&#xff1a; 实现代码与解析&#xff1a; dfs 原理思路&#xff1a; 1038. 从二叉搜索树到更大和树 题目描述&#xff1a; 给定一个二叉搜索树 root (BST)&#xff0c;请将它的每个节点的值替换成树中大于或者等于该节点值的所…

_____面试题_____(持续更新)

连表的链接方式 # 左连接 left join on # 右连接 right join on # 内连接 inner join on # 全连接 full join on # 笛卡尔积 join ------------------------------------------------ 上面讲的都是连表方式&#xff0c;连表的目的是查询&#xff0c;连表的依据是表和表…

探索人工智能领域——每日20个名词详解【day8】

目录 前言 正文 总结 &#x1f308;嗨&#xff01;我是Filotimo__&#x1f308;。很高兴与大家相识&#xff0c;希望我的博客能对你有所帮助。 &#x1f4a1;本文由Filotimo__✍️原创&#xff0c;首发于CSDN&#x1f4da;。 &#x1f4e3;如需转载&#xff0c;请事先与我联系以…

STM32存储左右互搏 SPI总线读写FRAM MB85RS16

STM32存储左右互搏 I2C总线读写FRAM MB85RS16 在中低容量存储领域&#xff0c;除了FLASH的使用&#xff0c;&#xff0c;还有铁电存储器FRAM的使用&#xff0c;相对于FLASH&#xff0c;FRAM写操作时不需要预擦除&#xff0c;所以执行写操作时可以达到更高的速度&#xff0c;其…

【自习室预约系统源码】基于springboot框架的自习室管理和预约系统设计

&#x1f345; 简介&#xff1a;500精品计算机源码学习 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 文末获取源码 目录 一、以下学习内容欢迎领取&#xff1a; 二、文档资料截图&#xff1a; 三想了解更多&#xff0c;请收藏、评论、留言&#xff1a;…

Android Studio的笔记--String和byte[]

String和byte[]的相互转换&#xff0c;字节数组转换 String转换byte[]文本16进制字节数组 byte[]转换String文本16进制 其它 String转换byte[] 文本 将字符串&#xff08;String&#xff09;转换为字节&#xff08;byte&#xff09;的方法。默认使用的是UTF-8编码 StandardCh…

SQL数据库知识点总结归纳

前后顺序可以任意颠倒,不影响库中的数据关系 关系数据库的逻辑性强而物理性弱,因此关系数据库中的各条记录前后顺序可以任意颠倒,不影响库中的数据关系 一名员工可以使用多台计算机(1:m),而一台计算机只能被一名员工使用(1:1),所以员工和计算机两个实体之间是一对多…

学习前端都需要学什么?

前端开发是一门需要掌握多种技术和工具的综合性学科。作为一名合格的前端开发者&#xff0c;需要具备以下几方面的知识和技能&#xff1a; HTML&#xff1a;HTML 是构建网页的基础&#xff0c;是前端开发的第一步。需要掌握各种 HTML 标签的使用和语义化的编写方式&#xff0c…