栈和队列就是这么简单

Java - 数据结构,栈 java虚拟机栈也是栈,就是JVM中的一块内存,也是符合栈的规则 – 先进后出规则方法区:存放类定义信息、字节码、常量等数据,在Sun HotSpot JVM中,这块也称为Perm Gen。堆:创建的对象信息将放入堆中,堆内部如何实现各虚拟机各不相同,对于Sun HotSpot JVM来说又分为Young Gen和Tenured Gen,更详细描述参见《[Java性能剖析]Sun JVM内存管理和垃圾回收 》 阅读详情

 

一、前言

上一篇已经讲过了链表【Java实现单向链表】了,它跟数组都是线性结构的基础,本文主要讲解线性结构的应用:栈和队列

如果写错的地方希望大家能够多多体谅并指正哦,如果有更好的理解的方式也希望能够在评论下留言,让大家学习学习~

二、数据结构【栈】就是这么简单

2.1数据结构【栈】介绍

数据结构的栈长的是这个样子:

640?wx_fmt=jpeg

其实非常好理解,我们将栈可以看成一个箱子

说到栈的特性,肯定会有一句经典的言语来概括:先进后出(LIFO, Last In First Out)

2.2数据结构【栈】 代码实现

栈的分类有两种:

从上一篇写链表我就认知到我的算法是有多渣了,普通的单链表操作也能把我绕得晕晕的。

由于我的链表还不是很熟,栈又不是很难,那么我就用链表来创建动态栈了!

既然是用链表,我们还是把上一篇节点的代码拿过来吧:

public class Node {    //数据域    public int data;    //指针域,指向下一个节点    public Node next;    public Node() {    }    public Node(int data) {        this.data = data;    }    public Node(int data, Node next) {        this.data = data;        this.next = next;    }}class Node {

   //数据域
   public int data;

   //指针域,指向下一个节点
   public Node next;

   public Node() {
   }

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

   public Node(int data, Node next) {
       this.data = data;
       this.next = next;
   }

}

要链表用来表示栈,这次会有两个指针:

public class Stack {    public Node stackTop;    public Node stackBottom;    public Stack(Node stackTop, Node stackBottom) {        this.stackTop = stackTop;        this.stackBottom = stackBottom;    }    public Stack() {    }}class Stack {

   public Node stackTop;
   public Node stackBottom;

   public Stack(Node stackTop, Node stackBottom) {
       this.stackTop = stackTop;
       this.stackBottom = stackBottom;
   }

   public Stack() {
   }


}

2.2.1进栈

将原本栈顶指向的节点交由新节点来指向,栈顶指向新加入的节点

    /**     * 进栈     *     * @param stack 栈     * @param value 要进栈的元素     */    public static void pushStack(Stack stack, int value) {        // 封装数据成节点        Node newNode = new Node(value);        // 栈顶本来指向的节点交由新节点来指向        newNode.next = stack.stackTop;        // 栈顶指针指向新节点        stack.stackTop = newNode;    }
   public static void pushStack(Stack stack, int value) {

       // 封装数据成节点
       Node newNode = new Node(value);


       // 栈顶本来指向的节点交由新节点来指向
       newNode.next = stack.stackTop;

       // 栈顶指针指向新节点
       stack.stackTop = newNode;

   }

2.2.2遍历栈

只要栈顶元素的指针不指向栈底,那么就一直输出遍历结果:

    /**     * 遍历栈(只要栈顶指针不指向栈底指针,就一直输出)     *     * @param stack     */    public static void traverse(Stack stack) {        Node stackTop = stack.stackTop;        while (stackTop != stack.stackBottom) {            System.out.println("关注公众号:Java3y:" + stackTop.data);            stackTop = stackTop.next;        }    }
   public static void traverse(Stack stack) {
       Node stackTop = stack.stackTop;

       while (stackTop != stack.stackBottom) {

           System.out.println("关注公众号:Java3y:" + stackTop.data);

           stackTop = stackTop.next;
       }


   }

测试:

    public static void main(String[] args) {        //初始化栈(无元素)        Stack stack = new Stack(new Node(), new Node());        //栈顶和栈尾是同一指向        stack.stackBottom = stack.stackTop;        //指向null        stack.stackTop.next = null;        //进栈        pushStack(stack, 3);        pushStack(stack, 4);        pushStack(stack, 5);        traverse(stack);    }

       //初始化栈(无元素)
       Stack stack = new Stack(new Node(), new Node());

       //栈顶和栈尾是同一指向
       stack.stackBottom = stack.stackTop;

       //指向null
       stack.stackTop.next = null;


       //进栈
       pushStack(stack, 3);
       pushStack(stack, 4);
       pushStack(stack, 5);

       traverse(stack);

   }

结果:

640?wx_fmt=png

这就符合了先进后出的特性了~

2.2.3判断该栈是否为空

很简单,只要栈顶和栈底是同一指向,那么该栈就为空

    /**     * 判断该栈是否为空     *     * @param stack     */    public static void isEmpty(Stack stack) {        if (stack.stackTop == stack.stackBottom) {            System.out.println("关注公众号:Java3y---->该栈为空");        } else {            System.out.println("关注公众号:Java3y---->该栈不为空");        }    }
   public static void isEmpty(Stack stack) {
       if (stack.stackTop == stack.stackBottom) {

           System.out.println("关注公众号:Java3y---->该栈为空");
       } else {

           System.out.println("关注公众号:Java3y---->该栈不为空");

       }

   }

2.2.4出栈

  1. 在出栈之前看看该栈是否为空,不为空才出栈…

  2. 将栈顶的元素的指针(指向下一个节点)赋值给栈顶指针(完成出栈)

    /**     * 出栈(将栈顶的指针指向下一个节点)     * @param stack     */    public static void popStack(Stack stack) {        // 栈不为空才能出栈        if (!isEmpty(stack)) {            //栈顶元素            Node top = stack.stackTop;            // 栈顶指针指向下一个节点            stack.stackTop = top.next;            System.out.println("关注公众号:Java3y---->出栈的元素是:" + top.data);        }    }
   public static void popStack(Stack stack) {

       // 栈不为空才能出栈
       if (!isEmpty(stack)) {

           //栈顶元素
           Node top = stack.stackTop;

           // 栈顶指针指向下一个节点
           stack.stackTop = top.next;

           System.out.println("关注公众号:Java3y---->出栈的元素是:" + top.data);

       }
   }

测试出栈:

640?wx_fmt=png

多次出栈:

640?wx_fmt=png

2.2.5清空栈

当时学C的时候需要释放内存资源,可是Java不用呀,所以栈顶指向栈底,就清空栈了

    /**     * 清空栈     * @param stack     */    public static void clearStack(Stack stack) {        stack.stackTop = null;        stack.stackBottom = stack.stackTop;    }
   public static void clearStack(Stack stack) {

       stack.stackTop = null;
       stack.stackBottom = stack.stackTop;
   }

三、数据结构【队列】就是这么简单

数据结构的队列长的是这个样子:

640?wx_fmt=jpeg

其实队列非常好理解,我们将队列可以看成小朋友排队

相对于栈而言,队列的特性是:先进先出

队列也分成两种:

这次我就使用数组来实现静态队列了。值得注意的是:往往实现静态队列,我们都是做成循环队列

640?wx_fmt=jpeg

做成循环队列的好处是不浪费内存资源!

3.1数据结构【队列】 代码实现

这次我们使用的是数组来实现静态队列,因此我们可以这样设计:

public class Queue {    //数组    public int [] arrays;    //指向第一个有效的元素    public int front;    //指向有效数据的下一个元素(即指向无效的数据)    public int rear;}class Queue {


   //数组
   public int [] arrays;

   //指向第一个有效的元素
   public int front;

   //指向有效数据的下一个元素(即指向无效的数据)
   public int rear;

}

从上面的设计我们可以发现:rear并不指向最后一个有效的元素,在循环队列中这样设计是非常方便的!因为这样设计可以让我们分得清队头和队尾(不然循环队列不断入队或出队,位置是变化很快的)

由于我们是循环队列,所以front和rear值会经常变动,我们得把front和rear的值限定在一个范围内,不然会超出队列的长度的。

有这么一个算法:rear=(rear+1)%数组长度

3.1.2初始化队列

此时队列为空,分配了6个长度给数组(只能装5个实际的数字,rear指向的是无效的位置的)

    public static void main(String[] args) {        //初始化队列        Queue queue = new Queue();        queue.front = 0;        queue.rear = 0;        queue.arrays = new int[6];    }

       //初始化队列
       Queue queue = new Queue();

       queue.front = 0;
       queue.rear = 0;
       queue.arrays = new int[6];

   }

3.1.3判断队列是否满了

如果rear指针和front指针紧挨着,那么说明队列就满了

    /**     * 判断队列是否满了,front和rear指针紧挨着,就是满了     * @param queue     * @return     */    public static boolean isFull(Queue queue) {        if ((queue.rear + 1) % queue.arrays.length == queue.front) {            System.out.println("关注公众号:Java3y--->此时队列满了!");            return true;        } else {            System.out.println("关注公众号:Java3y--->此时队列没满了!");            return false;        }    }
   public static boolean isFull(Queue queue) {
       if ((queue.rear + 1) % queue.arrays.length == queue.front) {

           System.out.println("关注公众号:Java3y--->此时队列满了!");
           return true;
       } else {
           System.out.println("关注公众号:Java3y--->此时队列没满了!");
           return false;
       }
   }

3.1.4入队

  1. 判断该队列是否满了

  2. 入队的值插入到队尾中(具体的位置就是rear指针的位置【再次声明:rear指向的是无效元素的位置】

  3. rear指针移动(再次指向无效的元素位置)

    /**     * 入队     *     * @param queue     */    public static void enQueue(Queue queue,int value) {        // 不是满的队列才能入队        if (!isFull(queue)) {            // 将新的元素插入到队尾中            queue.arrays[queue.rear] = value;            // rear节点移动到新的无效元素位置上            queue.rear = (queue.rear + 1) % queue.arrays.length;        }    }
   public static void enQueue(Queue queue,int value) {

       // 不是满的队列才能入队
       if (!isFull(queue)) {

           // 将新的元素插入到队尾中
           queue.arrays[queue.rear] = value;

           // rear节点移动到新的无效元素位置上
           queue.rear = (queue.rear + 1) % queue.arrays.length;
       }
   }

3.1.5遍历

只要front节点不指向rear节点,那么就可以一直输出

    /**     * 遍历队列     * @param queue     *     */    public static void traverseQueue(Queue queue) {        // front的位置        int i = queue.front;        while (i != queue.rear) {            System.out.println("关注公众号:Java3y--->" + queue.arrays[i]);            //移动front            i = (i + 1) % queue.arrays.length;        }    }
   public static void traverseQueue(Queue queue) {

       // front的位置
       int i = queue.front;

       while (i != queue.rear) {

           System.out.println("关注公众号:Java3y--->" + queue.arrays[i]);

           //移动front
           i = (i + 1) % queue.arrays.length;
       }

   }

队列没满时:

640?wx_fmt=png

队列已满了就插入不了了(验证上面的方法是否正确):

640?wx_fmt=png

3.1.6判断该队列是否为空

只要rear和front指针指向同一个位置,那该队列就是空的了

    /**     * 判断队列是否空,front和rear指针相等,就是空了     * @param queue     * @return     */    public static boolean isEmpty(Queue queue) {        if (queue.rear  == queue.front) {            System.out.println("关注公众号:Java3y--->此时队列空的!");            return true;        } else {            System.out.println("关注公众号:Java3y--->此时队列非空!");            return false;        }    }
   public static boolean isEmpty(Queue queue) {
       if (queue.rear  == queue.front) {
           System.out.println("关注公众号:Java3y--->此时队列空的!");
           return true;
       } else {
           System.out.println("关注公众号:Java3y--->此时队列非空!");
           return false;
       }
   }

3.1.7出队

出队的逻辑也非常简单:

  1. 判断该队列是否为null

  2. 如果不为null,则出队,只要front指针往后面移就是出队了!

     /**     * 出队     *     * @param queue     */    public static void outQueue(Queue queue) {        //判断该队列是否为null        if (!isEmpty(queue)) {            //不为空才出队            int value = queue.arrays[queue.front];            System.out.println("关注公众号:Java3y--->出队的元素是:" + value);            // front指针往后面移            queue.front = (queue.front + 1) % queue.arrays.length;        }    }
   public static void outQueue(Queue queue) {

       //判断该队列是否为null
       if (!isEmpty(queue)) {


           //不为空才出队
           int value = queue.arrays[queue.front];
           System.out.println("关注公众号:Java3y--->出队的元素是:" + value);

           // front指针往后面移
           queue.front = (queue.front + 1) % queue.arrays.length;

       }


   }

结果:

640?wx_fmt=png

四、总结

数据结构的栈和队列的应用非常非常的多,这里也只是最简单的入门,理解起来也不困难。

关于数据结构这方面我就到暂时到这里为止了,都简单的入个门,以后遇到更加复杂的再继续开新的文章来写~毕竟现在水平不够,也无法理解更深层次的东西~数据结构这东西是必备的,等到研究集合的时候还会来回顾它,或者遇到新的、复杂的也会继续学习….

想要更加深入数据结构的同学就得去翻阅相关的书籍咯~这仅仅是冰山一角

如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y


栈和队列的简单实现 栈和队列的介绍,以及简单的代码实现 阅读详情

相关推荐

VCSA的vmware-updatemgr服务无法启动和vSAN界面报“certificate chain is not trusted and thumbprint doesn‘t match”处理

"Unable to update CM service info"和"Server certificate chain is not trusted and thumbprint doesn't match"问题处理

jetliu05的博客 1883

深入理解Java中的栈(超详细)新手必看

栈(Stack)是一种常见的数据结构,具有后进先出(LIFO,Last In First Out)的特性,即最后入栈的元素最先出栈。栈通常用于存储临时性的数据,如方法调用过程中的局部变量、操作数栈等。在计算机科学中,栈的应用非常广泛,包括编程语言中的函数调用、内存分配以及表达式求值等领域。在Java编程语言中,栈也被广泛应用于方法调用和内存管理的过程中。双端栈(Double Ended Stack),也被称为双端队列(Deque),是一种支持在两端进行插入和删除操作的数据结构。

2201_75437633的博客 2万+

国产麒麟系统下Kettle安装避坑指南:解决aarch64架构不支持问题

本文详细解析了在国产麒麟系统上部署Kettle时遇到的aarch64架构不支持问题,提供了从获取适配的SWT库、修改启动脚本到生产环境调优的完整解决方案。文章重点解决了ARM架构与Java GUI工具的兼容性挑战,并分享了内存配置、字体显示及Carte服务部署等实战经验,助力用户在国产化环境中稳定运行ETL流程。

weixin_29197835的博客 561

Java数据结构-栈

栈

Vampire的博客 5641

Linux磁盘扩容实战:用parted命令无损扩展/data分区(附常见报错解决方案)

本文详细介绍了在Linux生产环境中使用parted命令对已挂载的/data分区进行在线磁盘扩容的完整实战流程。通过风险评估、状态检查、parted工具深度解析及实战演练,指导用户安全完成动态扩容,并提供了常见报错如'Partition is being used'、MBR 2TB限制等的解决方案,确保业务不中断、数据不丢失。

weixin_29207439的博客 297

各种加法器的比对分析与Verilog实现(3)

了Kogge-Stone加法器和brent-kung加法器,本文将用Verilog代码进行实现。

Albert_yeager的博客 1198

Java数据结构01——栈

java java数据结构 栈

qq_64037280的博客 4385

在带有Intel Arc GPU的Windows上安装IPEX-LLM

本文将介绍在 Intel Arc GPU 环境下安装 IPEX-LLM。

wux_labs的博客 1635

java中的栈

本文阐述了对栈数据结构的理解,展示了继承关系,针对Stack被弃置的问题展开了探讨,具体解释了被弃置的原因,如何替代,使用队列实现栈的算法以及在面试中如何看待Stack。

Archiea的博客 1万+

无人机导航中的坐标系统详解与转换实现

本文系统介绍了无人机导航中常用的坐标系及其转换方法。主要内容包括:1) 四种关键坐标系(大地坐标系ECEF、经纬度LLA、北东天坐标系NED、机体坐标系)的定义和特点;2) 坐标系间的转换原理与实现,重点讲解LLA与ECEF的互转公式及ECEF与NED的转换方法;3) 提供可直接使用的C++实现代码,包括基于WGS84椭球模型的精确转换算法。这些内容为无人机导航系统开发提供了实用的坐标系处理方案,能够有效解决多源数据在不同坐标系下的统一表示问题。

电脑管家 377

21天教你学会PCIe专栏(21)--总结和展望

回顾整个课程的主要内容和知识点总结PCIe技术的发展历程和现状展望PCIe技术的未来发展趋势和应用方向分享学习心得和实践经验1.1 课程回顾基础知识:了解了PCIe的基本概念、发展历程、标准和规范。分层结构:学习了PCIe的物理层、数据链路层和事务层的结构和功能。功能和特性:掌握了PCIe的热插拔、电源管理、多功能设备等高级功能。高速接口技术:学习了PCIe 4.0、5.0和未来趋势。实际案例分析:分析了GPU加速器和存储设备的PCIe设计和优化。常见问题和解决方案。

xiaoheshang_123的博客 672

利用栈和队列实现简单的四则运算

一、介绍 简单的四则运算,只是包含整数和加减乘除和左右括号的运算。 利用队列先进先出的特性,存储整个运算公式各个元素。 利用栈后进先出的特性,存储数字和运算符 二、过程 1.整个运算公式的各个元素入队列。 2.队列中的元素出栈 1)如果是数字,进入数字栈,再次队伍元素出队。 这里插入左右括号的处理。 如果是左括号符号,该左括号入符号栈,再次队列元素出队。 如果是右括号符号,就需要不断将符号栈中的元...

我是传奇 3737

【WorkBuddy从入门到精通实战教程】第 4 章 快速完成第一个 WorkBuddy 任务

摘要:WorkBuddy任务创建指南详细说明了从新建任务到结果验收的全流程。操作步骤包括:选择工作目录、设置模式(Craft/Ask/Plan)、指定AI模型、输入任务说明(需包含目标/输入/动作/约束/输出/验收6要素),可选配Skill等高级设置。文中提供三个入门示例:A)文件整理需保持原文件并生成分类方案;B)会议纪要要求结构化输出且所有内容有原文依据;C)Word转PPT需遵循品牌规范并控制页数。特别强调首次操作应在演练目录测试,处理真实数据前需确认授权范围,输出文件需检查涉密信息并按规范共享。(1

企鹅码农的专属播客,分享10多年的实战案例和经验解读,包含YOLO、RT-DETR、AI等各个工作领域。 1352

python 栈和队列_Python实现栈和队列的简单操作方法示例

本文实例讲述了Python实现栈和队列的简单操作方法。分享给大家供大家参考,具体如下:先简单的了解一下数据结构里面的栈和堆:栈和队列是两种基本的数据结构,同为容器类型。两者根本的区别在于:stack:后进先出queue:先进先出stack和queue是不能通过查询具体某一个位置的元素而进行操作的。但是他们的排列是按顺序的对于stack我们可以使用python内置的list实现,因为list是属于线...

weixin_39988164的博客 135

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

栈和队列简单总结

文章目录栈和队列栈栈的简介栈的常见应用自己实现一个栈队列队列的两种实现方式基于链表实现的队列 栈和队列 站和队列都是线性表,都是基于List基础上实现的 线性表就是元素按照一条"直线排列起来",线性表这个结构中,一次添加单个元素,常见的线性表有:数组,链表,字符串,栈和队列 常见的非线性结构有:树,图 站和队列是一个再使用上更加严格的线性表,规定了添加元素和输出元素的规则 动态数组,链表,可以在任意位置进行插入和删除 栈 栈的简介 栈是一个先进后出,后进先出的线性表,支持三个核心的操作:入栈(pus

weixin_45809829的博客 620

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

栈和队列的Java实现_栈和队列的java简单实现

栈:这是一个先进后出的数据结构,生活中类似的浏览器的返回上一页就可以利用此结构实现,代码如下:public class Stack{private Object[] data;//存储数据private int top;//表示栈顶元素publicStack(){data= new Object[100];//为了说明原理随意指定top =-1;}public synchronized void ...

weixin_34138192的博客 216

栈和队列简单例题

ACboy needs your help again! Input The input contains multiple test cases. The first line has one integer,represent the number oftest cases. And the input of each subproblem are described above. Outpu...

qq_37864983的博客 1041

栈和队列以及简单应用

栈和队列的实现以及简单应用

FUTURE_Boolean的博客 906

简单的栈和队列

栈: 栈:限定仅在表尾进行插入和删除操作的线性表。 允许插入和删除的一端称为栈顶,另一端称为栈底。 #include<iostream> using namespace std; const int MAX_SIZE=100; template <class T> class seqStack { public: seqStack(){};...

qq_43627089的博客 156

【栈和队列】C语言简单应用 ⌊栈和队列互相实现,循环队列⌉

栈和队列简单应用

qq_62852431的博客 2299

栈和队列的java简单实现

  栈:这是一个先进后出的数据结构,生活中类似的浏览器的返回上一页就可以利用此结构实现,代码如下: public class Stack&lt;T&gt; { private Object[] data;//存储数据 private int top;//表示栈顶元素 public Stack(){ data = new Object[100]...

weixin_34302561的博客 122

数据结构栈和队列的简单实现

栈:数据先进后出 在这里可以先用数组来实现 定义一个指针 栈空的时候指向栈底。把 队列:先进先出 也先用数组来实现:

qq_45841224的博客 167

栈和队列的简单运用

栈和队列 1.根据入栈出栈规律,判断顺序是否合理 实现思路: 直接使用栈试错,其中inOutOrder为原始数据,outOrder为需要判断的顺序,inOutOrder根据outOrder判断入栈出栈规则 public boolean isOutOrder(int[] inOutOrder, int[] outOrder) { if (inOutOrder == null || outOrder == null || inOutOrder.length != outOrder.len

qq_45676647的博客 288

栈和队列的简单介绍

循环队列,顾名思义,循环队列就是形成一个圈,但是并不是简单的首尾相接,但是,在实际使用中,我们往往在首尾之间会空下一个格,当。如果说做一个比喻:栈是描述叠盘子的规则,虚拟机栈是放盘子的架子,栈帧是每一个盘子。,队列入队列出队列时先进先出,插入操作的一端是。栈帧:是虚拟栈的每一个元素或者是一个方法调用。栈:只是一种数据结构,是描述某种东西的概念。在队列的使用过程中,实际上是链式结构更好;,进行数据插入和删除的一端称为。实现队列,我们需要使用接口。栈是一种特殊的线性表,,底层是通过链表实现的。

qq_61174226的博客 625

栈和队列简单介绍

数据结构 栈是一种类似桶的数据结构,因为最先进入栈的元素像被压在桶底的物品一样,只有拿掉在其之后放入的物品,才能将其取出。严格来讲就是进栈、退栈 队列是一种类似管道的数据结构,因为最先进入队列的元素像在管道中物品一样,第几个进去,就是第几个出来,先进去的先出来。也就是入队和出队

cqbzcgz的博客 689
上一篇: Java实现单向链表基本功能
下一篇: 【Java实现】栈和队列就是这么简单
Java3y
Java3y 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 1万+粉丝 509原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值