Java 数据结构篇-用链表、数组实现栈

🔥博客主页: 【小扳_-CSDN博客】
❤感谢大家点赞👍收藏⭐评论✍
  

文章目录

        1.0 栈的说明

        2.0 用链表来实现栈

        2.1 实现栈 - 入栈方法(push)

        2.2 实现栈 - 出栈(pop)

        2.3 实现栈 - 查看栈顶元素(peek)

        2.4 实现栈 - 判断是否为空栈(isEmpty)

        2.5 实现栈 - 判断是否为满栈(isFull)

        2.6 实现栈 - 重写迭代器

        2.7 用链表实现栈的完整代码

        3.0 用数组来实现栈

        3.1 实现栈 - 入栈(push)

        3.2 实现栈 - 出栈(pop)

        3.3 实现栈 - 查找栈顶元素(peek)

        3.4 实现栈 - 判断是否为空栈(isEmpty)

        3.5 实现栈 - 判断是否为满栈(isFull)

        3.6 实现栈 - 重写迭代器

        3.7 用数组实现栈的完整代码


        1.0 栈的说明

        栈是一种数据结构,它具有后进先出(LIFO)的特性,即最后入栈的元素最先出栈。栈通常可以通过数组或链表来实现。栈有两个基本操作:入栈(push)出栈(pop)。入栈操作将元素放入栈顶,出栈操作将栈顶元素移除并返回。栈还有一个辅助操作叫做查看栈顶元素(peek),用于查看栈顶的元素但不移除它

        2.0 用链表来实现栈

        首先,需要准备实现带哨兵的单链表,用来存放数据。把链表的头部称为栈顶,链表的尾部称为栈底,对于栈来说,只对栈顶操作,对栈底不会有任何的操作。所以该链表中需要的成员变量有 sentry 哨兵节点、 size 记录节点的数量capacity 栈的容量。为了更好的实现相关的API,所以另外定义了一个接口。

代码如下:


public class LinkedListStack<E> implements StackInterface<E>{static class Node<E> {public E value;Node<E> next;public Node() {}public Node(E value, Node<E> next) {this.value = value;this.next = next;}}private int size;private final int capacity;private final Node<E> sentry;public LinkedListStack(int capacity) {this.capacity = capacity;this.sentry = new Node<>(null,null);}}

        

        2.1 实现栈 - 入栈方法(push)

        用链表实现栈中,入栈就相当于在链表中进行头插节点,需要注意的是,在进行入栈的时候需要先判断是否栈满了,若栈满了,返回 false;反则,返回 true 。

代码如下:

    public boolean push(E value) {if (isFull()) {System.out.println("栈容量满了!!!");return false;}sentry.next = new Node<>(value,sentry.next);size++;return true;}

        sentry.next 所指向的就是头节点,现在头节点要换成新入栈的节点,则就是 sentry.next 指向该节点,而新入栈的节点指向原来就旧的头节点。需要注意的是,记得进行 size++

        2.2 实现栈 - 出栈(pop)

        用链表实现栈中,出栈相当于头删节点,不过结束的时候需要返回该节点的值,所以先找到头节点 head = sentry.next ,然后再让哨兵节点指向头节点的下一个节点,即可将该头节点从该链表中删除掉了,sentry.next = head.next 。最后返回 head.value

代码如下:

    public E pop() {if (isEmpty()) {return null;}Node<E> first = sentry.next;sentry.next = first.next;size--;return first.value;}

        在进行出栈操作时,需要先判断该链表是否为空,若是空链表,则返回 null ;若不是空链表,则返回该删除节点的值。还需要注意的是,每一次删除后,都需要进行 size-- 操作。

        2.3 实现栈 - 查看栈顶元素(peek)

        用链表实现栈中,查看栈顶元素相当与查找头节点,即 head =  sentry.next,因此直接返回该头节点的值即可 head.value

    @Overridepublic E peek() {if (isEmpty()) {return null;}Node<E> first = sentry.next;return first.value;}

        在查看栈顶元素时,也要先判断该栈是否为空栈。若为空栈,直接返回 null

        2.4 实现栈 - 判断是否为空栈(isEmpty)

        当且仅当 size == 0 时,则为空栈。还有一种判断的方式,就是当 sentry.next 时,也为空栈

代码如下:

    public boolean isEmpty() {return size == 0;//return sentry.next == null;}

        2.5 实现栈 - 判断是否为满栈(isFull)

        用链表实现栈时,当 size == capacity 时,则为满栈

代码如下:

    public boolean isFull() {return size == capacity;}

         2.6 实现栈 - 重写迭代器

        先实现该接口 Iterable<E> ,再重写该接口的两个方法,hasNext() next() 。对于 hasNext() ,当 p != null 时,继续循环下去,p == null 时,循环结束;对于 next() ,需要进行 p = p.next,将 p 往后移一步的动作,还得需要完成每一次返回对应的数据的动作。 

代码如下:

    public Iterator<E> iterator() {return new Iterator<E>() {Node<E> p = sentry.next;@Overridepublic boolean hasNext() {return p != null;}@Overridepublic E next() {E key = p.value;p = p.next;return key;}};}

        2.7 用链表实现栈的完整代码

相关的接口:

public interface StackInterface <E>{/*** 先栈顶压入元素* value - 代压入值* 压入成功返回true,否则返回false*/boolean push(E value);/*** 从栈顶弹出元素* 栈非空返回栈顶元素,栈为空返回 null*/E pop();/**返回栈顶元素,不弹出栈非空返回栈顶元素,栈为空返回 null*/E peek();/*** 判断栈是否为空* 空返回true,否则返回false*/boolean isEmpty();/*** 判断栈是否满* 满返回true,否则返回false*/boolean isFull();}

用链表实现栈的代码:

import java.util.Iterator;
public class LinkedListStack<E> implements StackInterface<E>,Iterable<E>{static class Node<E> {public E value;Node<E> next;public Node() {}public Node(E value, Node<E> next) {this.value = value;this.next = next;}}private int size;private final int capacity;private final Node<E> sentry;public LinkedListStack(int capacity) {this.capacity = capacity;this.sentry = new Node<>(null,null);}@Overridepublic boolean push(E value) {if (isFull()) {System.out.println("栈容量满了!!!");return false;}sentry.next = new Node<>(value,sentry.next);size++;return true;}@Overridepublic E pop() {if (isEmpty()) {return null;}Node<E> first = sentry.next;sentry.next = first.next;size--;return first.value;}@Overridepublic E peek() {if (isEmpty()) {return null;}Node<E> first = sentry.next;return first.value;}@Overridepublic boolean isEmpty() {return size == 0;//return sentry.next == null;}@Overridepublic boolean isFull() {return size == capacity;}@Overridepublic Iterator<E> iterator() {return new Iterator<E>() {Node<E> p = sentry.next;@Overridepublic boolean hasNext() {return p != null;}@Overridepublic E next() {E key = p.value;p = p.next;return key;}};}
}

        3.0 用数组来实现栈

        该类中的成员变量有 Object[] array 的数组,来存放数据;还有 int top用来记录数据的个数,当 top - 1 索引对应该位置,称为栈顶0 索引对应的位置,称为栈底。这样的设置,提高了对栈顶操作的效率。

代码如下:

public class ArrayStack<E> {private int top;private Object[] arrayStack;public ArrayStack() {}public ArrayStack(int capacity) {arrayStack = new Object[capacity];}
}

        利用该类的构造方法,可以自定义初始化数组的容量。

        3.1 实现栈 - 入栈(push)

        用数组实现栈,相当与在数组 top 位置中存放数据,即 arrayStack[top] = value

代码如下:

 public boolean push(E value) {if (isFull()) {return false;}arrayStack[top++] = value;return true;}

        但是在入栈之前需要先判断该栈是否满了,若为满栈,则不能继续存放数据了。若存放数据之后,需要将 top++ 进行自加的操作。

        3.2 实现栈 - 出栈(pop)

        用数组实现栈,出栈相当于进行尾删,不过先得记录要删除的数据,将其返回即可。

代码如下:

    public E pop() {if (isEmpty()) {return null;}return (E)arrayStack[--top];}

        但是,在出栈之前需要先判断该栈是否为空栈。

         3.3 实现栈 - 查找栈顶元素(peek)

        用数组实现栈,查找栈顶元素相当于去查找数组 top - 1索引的值

代码如下:

    public E peek() {if (top == 0) {return  null;}return (E) arrayStack[top - 1];}

        在查找栈顶元素之前,需要先判断 top 是否为 0 ,为 0 即为空,没有必要查找了。

        3.4 实现栈 - 判断是否为空栈(isEmpty)

        用数组实现栈,判断是否为空栈,就是判断 top 是否等于 0 。

代码如下:

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

        3.5 实现栈 - 判断是否为满栈(isFull)

        用数组实现栈,判断是否为满栈,就是判断 top 是否等于该数组的长度 arrayStack.length 。

代码如下:

    @Overridepublic boolean isFull() {return arrayStack.length == top;}

        3.6 实现栈 - 重写迭代器

        先实现该接口 Iterable<E> ,再重写该接口的两个方法,hasNext()next() 。对于 hasNext() ,当 top > 0 时,继续循环下去,top == 0 时,循环结束;对于 next() ,完成需要进行 top-- 的动作,还得需要完成每一次返回对应的数据的动作。 

代码如下:

public Iterator<E> iterator() {return new Iterator<E>() {int p = top;@Overridepublic boolean hasNext() {return p > 0;}@Overridepublic E next() {return (E)arrayStack[--p];}};}

        3.7 用数组实现栈的完整代码

接口代码:

public interface StackInterface <E>{/*** 先栈顶压入元素* value - 代压入值* 压入成功返回true,否则返回false*/boolean push(E value);/*** 从栈顶弹出元素* 栈非空返回栈顶元素,栈为空返回 null*/E pop();/**返回栈顶元素,不弹出栈非空返回栈顶元素,栈为空返回 null*/E peek();/*** 判断栈是否为空* 空返回true,否则返回false*/boolean isEmpty();/*** 判断栈是否满* 满返回true,否则返回false*/boolean isFull();}

用数组实现栈的代码:

import java.util.Iterator;public class ArrayStack<E> implements StackInterface<E>,Iterable<E>{private int top;private Object[] arrayStack;public ArrayStack() {}public ArrayStack(int capacity) {arrayStack = new Object[capacity];}@Overridepublic boolean push(E value) {if (isFull()) {return false;}arrayStack[top++] = value;return true;}@Overridepublic E pop() {if (isEmpty()) {return null;}return (E)arrayStack[--top];}@Overridepublic E peek() {if (top == 0) {return  null;}return (E) arrayStack[top - 1];}@Overridepublic boolean isEmpty() {return top == 0;}@Overridepublic boolean isFull() {return arrayStack.length == top;}@Overridepublic Iterator<E> iterator() {return new Iterator<E>() {int p = top;@Overridepublic boolean hasNext() {return p > 0;}@Overridepublic E next() {return (E)arrayStack[--p];}};}
}

 

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

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

相关文章

国产linux单用户模式破解无密码登陆 (麒麟系统用户登录密码遗忘解决办法)

笔者手里有一批国产linu系统&#xff0c;目前开始用在日常的工作生产环境中&#xff0c;我这个老程序猿勉为其难的充当运维的或网管的角色。 国产linux系统常见的为麒麟Linux&#xff0c;统信UOS等&#xff0c;基本都是基于debian再开发的linux。 问题描述&#xff1a; 因为…

基于AT89C51单片机的倒数计时器设计

1&#xff0e;设计任务 利用AT89C51单片机为核心控制元件,设计一个简易的数字电压表&#xff0c;设计的系统实用性强、操作简单&#xff0c;实现了智能化、数字化。 本设计采用单片机为主控芯片&#xff0c;结合周边电路组成LED彩灯的闪烁控制系统器&#xff0c;用来控制红色…

用于缓存一些固定名称的小组件

项目中&#xff0c;用于缓存姓名、地名、单位名称等一些较固定名称的id-name小组件。用于减少一些表的关连操作和冗余字段。优化代码结构。扩展也方便&#xff0c;写不同的枚举就行了。 具体用法&#xff1a; {NameCacheUser.USER.getName(userId);NameCacheUser.ACCOUNT.getN…

excel合并单元格教程

在表格里&#xff0c;总是会遇到一级表格、二级表格的区别&#xff0c;这时候一级表格会需要合并成一个大格子&#xff0c;那么excel如何合并单元格呢&#xff0c;其实使用快捷键或者功能键就可以了。 excel如何合并单元格&#xff1a; 1、首先我们用鼠标选中所有要合并的单元…

最大公约数的C语言实现xdoj31

时间限制: 1 S 内存限制: 1000 Kb 问题描述: 最大公约数&#xff08;GCD&#xff09;指某几个整数共有因子中最大的一个&#xff0c;最大公约数具有如下性质&#xff0c; gcd(a,0)a gcd(a,1)1 因此当两个数中有一个为0时&#xff0c;gcd是不为0的那个整数&#xff…

XXL-Job详解(一):组件架构

目录 XXL-Job特性系统组成架构图调度模块剖析任务 “运行模式” 剖析执行器 XXL-Job XXL-JOB是一个分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线&#xff0c;开箱即用。 特性 1、简单&#…

java+springboot实验室管理系统的设计与实现ssm+jsp

课题研究内容&#xff1a; &#xff08;1&#xff09; 系统需求分析&#xff08;构成模块&#xff0c;系统流程&#xff0c;功能结构图&#xff0c;系统需求&#xff09; &#xff08;2&#xff09; 实验室课程安排功能模块&#xff08;课程的录入和调补&#xff09; &#xff…

wyler水平仪维修WYLER倾角仪维修CH-8405

瑞士WYLER电子水平仪维修&#xff1b;BIueCLINO倾斜度测量仪维修&#xff1b;wyler电子倾角仪维修。 水平仪常见故障及处理方法 1、 仪表通电不工作。 A、检查仪表220V电源端子接线是否正确 B、检查仪表电容是否熔断&#xff1b; C、拧下仪表后的固定螺钉&#xff0c;将表…

王道数据结构课后代码题p40 4.在带头结点的单链表L中删除一个最小值结点的高效算法(假设最小值唯一) (c语言代码实现)

本题代码为 void deletemin(linklist* L)//找到最小值并删除 {lnode* p (*L)->next, * pre *L;lnode* s p,*sprepre;while (p ! NULL)//找到最小值{if (p->data < s->data){s p;spre pre;}p p->next;pre pre->next;}p s->next;spre->next p;…

有IP没有域名可以申请证书吗?

一、IP证书是什么&#xff1f; ip证书是用于公网ip地址的SSL证书&#xff0c;与我们通常所讲的SSL证书并无本质上的区别&#xff0c;但由于SSL证书通常颁发给域名&#xff0c;而组织机构需要公共ip地址的SSL证书&#xff0c;这类SSL证书就是我们所说的ip证书。ip证书具有安全、…

仅仅通过提示词,GPT-4可以被引导成为多个领域的特定专家

The Power of Prompting&#xff1a;提示的力量&#xff0c;仅通过提示&#xff0c;GPT-4可以被引导成为多个领域的特定专家。微软研究院发布了一项研究&#xff0c;展示了在仅使用提策略的情况下让GPT 4在医学基准测试中表现得像一个专家。研究显示&#xff0c;GPT-4在相同的基…

上海毅速丨新材料将推动3D打印在压铸行业的应用

压铸是一种应用广泛的制造工艺&#xff0c;它的制造原理是将液态或半液态金属&#xff0c;在高压作用下&#xff0c;以高速度填充压铸模具型腔&#xff0c;并在压力下快速凝固而获得铸件的一种方法。压铸模的设计和制造需要考虑到多方面的因素&#xff0c;如模具材料、结构、冷…

设计模式详解(二):抽象工厂——Abstract Factory

目录导航 抽象工厂及其作用工厂方法的好处工厂方法的实现关系图实现步骤 工厂方法的适用场景工厂方法举例 抽象工厂及其作用 工厂方法是一种创建型设计模式。所谓创建型设计模式是说针对创建对象方面的设计模式。在面向对象的编程语言里&#xff0c;我们通过对象间的相互协作&…

SAP SD 创建交货单 报错 VL461 VL248

因为生产环境已经被改好了&#xff0c;无法跟踪 所以换到测试环境重现一把&#xff0c;如何追根究底 对比正常订单发现 计划行 VBEP-LMENG,VBEP-BMENG这两个字段上的值跟 订单数量不一致。 尝试修改2者的数据跟订单数据一致&#xff0c;则可以正常创建交货单 实际原因是&a…

【每日一坑】KiCAD导Gerber 文件

第一&#xff0c;软件版本 第二、操作选择注意点 第三&#xff0c;那个坑。。。 不知道什么原因&#xff0c;这第二个框里会选其他不必要得一些东西&#xff0c;导致最终光绘是废的&#xff1b; 一定切记只选edge.cut就好了。 最后&#xff0c;上Gerber图&#xff0c;还有一点…

机器学习入门(第六天)——支持向量机(升维打击)

Support vector machines 知识树 Knowledge tree 苹果表示重点 间隔&#xff1a;使用了几何间隔&#xff0c;保证w b的度量&#xff0c;感知机则是函数间隔 间隔最大化思想&#xff1a;则是支持向量机的独有&#xff0c;这使得它找到最优超平面 核函数&#xff1a;面试当中可…

防火墙补充NAT

目录 1.iptables保存规则 2.自定义链 3.NAT NAT的实现分为下面类型&#xff1a; SNAT实验操作 DNAT实验操作 1.iptables保存规则 永久保存方法一&#xff1a; iptables -save > /data/iptables_rule //输出重定向备份 iptables -restore < /data/iptables_r…

Windows安装Kafka3.6,单机

Kafka版本&#xff1a;kafka_2.13-3.6.0 Windows10系统 安装与配置 下载 kafka_2.13-3.6.0.tgz 下载并解压Kafka 3.6.0的压缩包到你选择的目录。 Kafka3.6.0下载链接https://kafka.apache.org/downloads 说明&#xff1a;Kafka3.6内置了Zookeeper&#xff0c;使用内置的Zo…

Ps:用好钢笔工具

使用钢笔工具时&#xff0c;应随时注意鼠标指针的形状。 ◆ ◆ ◆ 基本操作方法 1、绘制闭合路径 路径绘制结束时回到起点即可创建闭合路径。 2、绘制开放路径 想结束绘制时&#xff0c;按住 Ctrl 键点击画布空白处&#xff0c;或者&#xff0c;直接按 Esc 键&#xff0c;即可…

传统算法: Pygame 实现快速排序

使用 Pygame 模块实现了快速排序的动画演示。首先,它生成一个包含随机整数的数组,并通过 Pygame 在屏幕上绘制这个数组的条形图。接着,通过快速排序算法对数组进行排序,动画效果可视化每一步的排序过程。在排序的过程中,程序选择一个基准元素(pivot),将数组分成两部分,…