动图演示:手撸堆栈的两种实现方法!(三)

简介: 动图演示:手撸堆栈的两种实现方法!(三)

自定义栈II:链表实现

除了数组之外,我们可以还可使用链表来实现栈结构,它的实现稍微复杂一些,我们先来看链表本身的数据结构:

image.png

使用链表实现栈的流程如下:

image.png也就是说,入栈时我们将数据存储在链表的头部,出栈时我们从头部进行移除,并将栈顶指针指向原头部元素的下一个元素,实现代码如下。


我们先来定义一个链表节点:

public class Node {
    Object value; // 每个节点的数据
    Node next; // 下一个节点
    public Node(Object value) {
        this(value, null);
    }
    /**
     * 创建新节点
     * @param value 当前节点数据
     * @param next  指向下一个节点(头插法)
     */
    public Node(Object value, Node next) {
        this.value = value;
        this.next = next;
    }
}
接下来我们使用链表来实现一个完整的栈:
public class StackByLinked {
    private Node top = null; // 栈顶数据
    private int maxSize = 0; // 栈最大容量
    private int leng = 0; // 栈实际容量
    public StackByLinked(int initSize) throws Exception {
        if (initSize <= 0) {
            throw new Exception("栈容量不能小于等于0");
        }
        top = null;
        maxSize = initSize;
        leng = 0;
    }
    /**
     * 容量是否已满
     * @return
     */
    public boolean isFull() {
        return leng >= maxSize;
    }
    /**
     * 是否为空
     * @return
     */
    public boolean isEmpty() {
        return leng <= 0;
    }
    /**
     * 入栈
     * @param val
     * @return
     * @throws Exception
     */
    public boolean push(Object val) throws Exception {
        if (this.isFull()) {
            // 容量已满
            throw new Exception("容量已满");
        }
        top = new Node(val, top); // 存入信息,并将当前节点设置为头节点
        leng++;
        return true;
    }
    /**
     * 出栈(移除)
     * @return
     * @throws Exception
     */
    public Node pop() throws Exception {
        if (this.isEmpty()) {
            throw new Exception("栈为空,无法进行移除操作");
        }
        Node item = top; // 返回当前元素
        top = top.next;
        leng--;
        return item;
    }
    /**
     * 查询栈顶信息
     * @return
     */
    public Node peek() throws Exception {
        if (isEmpty()) {
            throw new Exception("你操作的是一个空栈");
        }
        return top;
    }
    // 代码测试
    public static void main(String[] args) throws Exception {
        StackByLinked stack = new StackByLinked(10);
        stack.push("Hello");
        stack.push("Java");
        System.out.println(stack.peek().value);
        stack.pop();
        System.out.println(stack.pop().value);
    }
}


以上程序的执行结果是:

Java

Hello


总结

本文我们使用了数组和链表等物理结构来实现了栈,当然我们也可以使用其他容器来实现,比如 Java 中的 List,我们只需要保证在操作栈时是后进先出的执行顺序,并且至少包含 3 个重要方法:入栈、出栈和查询栈顶元素就可以了。


最后

算法和数据结构的学习是 3 分学 7 分练,只看不练是没办法学好算法的,而且学习算法和数据结构是一个循序渐进的过程,短时间内不会有明显的收效。因为这些算法经过了几百年的发展和积累才得以流传下来的,所以想要“玩得转”还需要一点耐心。


这里给你讲一个学习算法的“秘诀”:看不懂的知识要反复看,如果反复看还是看不懂,那么别着急,休息一下再继续看!相信我,对于学习算法这件事,所有人的过程都是一样的。

相关文章
|
消息中间件 IDE JavaScript
用代码画时序图!YYDS
最近通过代码来看看这个图,给大家看图、UML ,感觉很给大家分享。 大家平时用他们出的图呢,是用什么样的图,都用画图来画的,我们用画图来画图 呢draw.io?processOn 今天给大家介绍一款想要的作品,用的画图,配合IDE使用PlantUML!
用代码画时序图!YYDS
|
4月前
|
数据可视化 算法 开发工具
微信小游戏制作工具中如何实现递归函数?
微信小游戏制作工具中如何实现递归函数?
31 0
|
5月前
|
C语言
井字棋的简单实现
井字棋的简单实现
33 0
|
9月前
|
设计模式 测试技术
【坦克大战一】——简单实现小结
小时候对于游戏的痴迷让我对于游戏有一种心底的渴望,然而随着时间的推移阅历、经历的增加以及现在从事的编程行业似乎和游戏越来越远;在工作中对技术的要求以及未来技术的分量加上一次偶然的机会重新燃起我对游戏的渴望,不过这次的游戏并不仅仅是痴迷,而是让自己拥有一颗归零的心态在游戏编程的角度去学习那些基础的知识。
|
9月前
|
存储 算法 Java
灰太狼系列之—自定义关卡推箱子(内含源码)
灰太狼系列之—自定义关卡推箱子(内含源码)
灰太狼系列之—自定义关卡推箱子(内含源码)
C代码程序实现扫雷游戏纯代码版本
C代码程序实现扫雷游戏纯代码版本
|
11月前
|
小程序 开发者
2行代码实现小程序分享到朋友圈功能
2行代码实现小程序分享到朋友圈功能
196 0
|
存储 C语言
【C语言】飞机大战游戏还原,源码在文末,应用“循环”与“数组”实现游戏开发,一起玩一下经典小游戏吧
众所周知昂,飞机大战,重在大战嘛,你这一颗子弹一架敌机,打的那是一点儿激情也没有。所以我们这章内容,就来对前文做修改,运用上数组手法,给它盘圆咯 在二维数组中存储游戏画面数据,元素为0时输出“ (空格)”,元素为1时输出大灰机“ * ”,元素为2输出子弹“¥”元素为3时输出敌机“@”定义二维数组存储游戏画面中元素的数组暂且定为4.基础功能的实现在飞机大战中,用人类语言来描述相关内容,则有以下这些,积分计算(包括击毁敌机,未击毁,飞机升级子弹,多架敌机产生……)这些我们都要一一实现 多架敌机产生这块儿,
【C语言】飞机大战游戏还原,源码在文末,应用“循环”与“数组”实现游戏开发,一起玩一下经典小游戏吧
|
Java
Java实现拼图小游戏(6)—— 移动图片(键盘监听实操练习)
当我们实现向上移动图片的时候,其实就是把空图片的下面一张图片往上移动,然后将空图片的下面那张图片设置为空图片,最后再调整初始位置为现在空图片所在位置即可,注意做完这些以后还要再加载图片,否则显示不出来
319 0
Java实现拼图小游戏(6)—— 移动图片(键盘监听实操练习)
|
Java
Java实现拼图小游戏(7)——查看完整图片(键盘监听实例2)
由于在移动和图片中我们已经添加了键盘监听,也继承了键盘监听的接口,那么我们只需要在重写方法内输入我们的代码即可
174 0