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.hqwc.cn/news/234051.html

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

相关文章

【JavaWeb】会话过滤器监听器

会话&过滤器&监听器 文章目录 会话&过滤器&监听器一、会话1.1 Cookie1.2 Session1.3 三大域对象 二、过滤器三、监听器3.1 application域监听器3.2 session域监听器3.3 request域监听器3.4 session域的两个特殊监听器3.4.1 session绑定监听器3.4.2 钝化活化监听…

MSUSB30模拟开关可Pin to Pin兼容FSUSB30/SGM7222

MSUSB30/MSUSB30N 是一款高速、低功耗双刀双掷 USB 模拟开关芯片&#xff0c;其工作电压范围是1.8V 至5.5V。可Pin to Pin兼容FSUSB30/SGM7222。其具有低码间偏移、高通道噪声隔离度、宽带宽的特性。 MSUSB30/MSUSB30N 主要应用范围包括&#xff1a;具有 USB2.0 接口的手持设备…

小程序禁止二次转发分享私密消息动态消息

第一种用法&#xff1a;私密消息 私密消息&#xff1a;运营人员分享小程序到个人或群之后&#xff0c;该消息只能在被分享者或被分享群内打开&#xff0c;不可以二次转发。 用途&#xff1a;主要用于不希望目标客群外的人员看到的分享信息&#xff0c;比如带有较高金额活动的…

在java java.util.Date 已知逝去时间怎么求年月日 数学计算不用其他方法

在Java中&#xff0c;使用java.util.Date类已知逝去时间求年月日的方法如下&#xff1a; 首先&#xff0c;获取当前时间和逝去时间之间的毫秒数差值&#xff0c;可以使用Date类的getTime()方法获得时间戳。 将毫秒数转换为秒数&#xff0c;并计算出总共的天数。 根据总共的天…

消除笔怎么用?手把手教你一键智能消除杂物

消除笔怎么用&#xff1f;消除笔是一种非常实用的工具&#xff0c;可以帮助我们快速修复图片中的小问题。无论是想要消除照片中的路人还是进行一些修改&#xff0c;消除笔都可以轻松地帮助我们实现。 以下是使用消除笔的步骤&#xff1a; 1、打开水印云软件&#xff0c;并在工具…

ProgrammingError: nan can not be used with MySQL

该错误怎么发生的&#xff1f; 我们先在本地创建测试表&#xff1a; CREATE TABLE users_test (id int NOT NULL AUTO_INCREMENT COMMENT 主键,trade_account varchar(50) DEFAULT NULL COMMENT 交易账号,username varchar(50) DEFAULT NULL,email varchar(100) DEFAULT NULL…

大数据HCIE成神之路之数学(4)——最优化实验

最优化实验 1.1 最小二乘法实现1.1.1 算法介绍1.1.2 代码实现1.2 梯度下降法实现1.2.1 算法介绍1.2.2 代码实现1.3 拉格朗日乘子法1.3.1 实验1.3.2 实验操作步骤1.1 最小二乘法实现 1.1.1 算法介绍 最小二乘法(Least Square Method),做为分类回归算法的基础,有着悠久的历…

【UE】简单的警觉系统

效果 步骤 1. 新建一个空白工程&#xff0c;添加第三人称游戏内容包 2. 打开第三人称角色蓝图“BP_ThirdPersonCharacter” 选中弹簧臂组件&#xff0c;将目标臂长度设置为600&#xff0c;z轴方向的插槽偏移设置为100 3. 将“BP_ThirdPersonCharacter”移入场景&#xff0c;该…

Glove学习笔记

global vectors for word representation B站学习视频 1、LSA与word2vec 我们用我们的见解&#xff0c;构建一个新的模型&#xff0c;Glove&#xff0c;全局向量的词表示&#xff0c;因为这个模型捕捉到全局预料的统计信息。 LSA:全局矩阵分解word2vec&#xff1a;局部上下文…

Flat Ads将携6亿独家流量亮相白鲸GTC2023,在7V01展台等你

一年一度的白鲸出海全球流量大会GTC重磅来袭!今年GTC出海展区全面升级,规模扩增至15000平方米,覆盖游戏、应用、技术及品牌出海等热门行业,预计将迎来累计超30000名跨境出海相关从业者莅临参观。 Flat Ads受邀设展,现场互动100%中奖 从出海到全球化,中国互联网企业走向海外寻…

深度学习大数据物流平台 python 计算机竞赛

文章目录 0 前言1 课题背景2 物流大数据平台的架构与设计3 智能车货匹配推荐算法的实现**1\. 问题陈述****2\. 算法模型**3\. 模型构建总览 **4 司机标签体系的搭建及算法****1\. 冷启动**2\. LSTM多标签模型算法 5 货运价格预测6 总结7 部分核心代码8 最后 0 前言 &#x1f5…

[个人笔记] Zabbix实现Webhook推送markdown文本

系统工程 - 运维篇 第四章 Zabbix实现Webhook推送markdown文本 系统工程 - 运维篇系列文章回顾Zabbix实现Webhook推送markdown文本前言实施步骤 Zabbix新增报警媒介类型Zabbix给用户新增报警媒介Zabbix修改动作的执行操作和恢复操作验证&测试 参考来源 系列文章回顾 第一章…