Java基础 - 栈

栈是一种遵循后进先出(LIFO)原则的数据结构,常用于浏览器的回退和前进、字符反转及分隔符匹配等场景。顺序栈通常使用一维数组实现,链式栈则依赖链表。本文将探讨Java中这两种栈的实现方式。

栈 (stack)又称堆栈,只允许在表的一端进行加入数据(push)和移除数据(pop)。因而按照 后进先出(LIFO, Last In First Out) 的原理运作。通常称能够进行插入、删除运算的一端为栈顶(Top),另一端称为栈底(Bottom)。当表中没有元素的时候称为空栈。

空栈时最先插入的元素总被放在栈的底部,只有所有元素被移除(弹出)后,它才能被删除

栈的存储结构有顺序存储结构和链式存储结构两种。在顺序栈中,可以考虑栈的上溢;在链式栈中,不必考虑栈的上溢,只需要考虑栈的下溢

栈的上溢是一种出错状态,应该设法避免;而下溢则是正常现象,可作为程序控制转移的条件

顺序栈

顺序栈 常用一维数组来实现

Java代码实现:

public class MyStack {
    private int[] storage;//存放栈中元素的数组
    private int capacity;//栈的容量
    private int count;//栈中元素数量
    private static final int GROW_FACTOR = 2;

    //不带初始容量的构造方法。默认容量为8
    public MyStack() {
        this.capacity = 8;
        this.storage=new int[8];
        this.count = 0;
    }

    //带初始容量的构造方法
    public MyStack(int initialCapacity) {
        if (initialCapacity < 1)
            throw new IllegalArgumentException("Capacity too small.");

        this.capacity = initialCapacity;
        this.storage = new int[initialCapacity];
        this.count = 0;
    }
}

链式栈

链式栈 常用链表来实现

Java代码实现:

public class LinkedList<E> {

    private class Node{
        public E e;
        public Node next;

        public Node(E e, Node next){
            this.e = e;
            this.next = next;
        }

        public Node(E e){
            this(e, null);
        }

        public Node(){
            this(null, null);
        }
    }

常见应用场景

浏览器的回退和前进

	我们只需要使用两个栈(Stack1 和 Stack2)和就能实现这个功能。比如你按顺序查看了 1,2,3,4 这四个页面,我们依次把 1,2,3,4 这四个页面压入 Stack1 中。当你想回头看 2 这个页面的时候,你点击回退按钮,我们依次把 4,3 这两个页面从 Stack1 弹出,然后压入 Stack2 中。假如你又想回到页面 3,你点击前进按钮,我们将 3 页面从 Stack2 弹出,然后压入到 Stack1 中。

反转字符

	利用栈后进先出的特征,将栈中的每个字符先入栈,再出栈即可。

分隔符匹配

	栈通常用于解析某种类型的文本串。通常,文本串是用计算机语言写的代码行,而解析它们的程序就是编译器。

	分隔符匹配程序从字符串不断地读取字符,若它是左分隔符,则压入栈中。当从输入中读取到一个右分隔符时,弹出栈顶的左分隔符,并查看它和右分隔符是否匹配。如果栈中没有匹配的左右分隔符,或栈中一直存在着没有被匹配的分隔符(所有字符读入后,栈中仍有分隔符),则程序报错。

Java中的代码实现:
public class BracketChecker {

    public static void main(String[] args) {
        String s ;
        s = getString();
        BracketChecker bracketChecker = new BracketChecker(s);
        bracketChecker.check();
    }
    private String input;

    public BracketChecker(String input) {
        this.input = input;
    }

    public void check() {
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < input.toCharArray().length; i++) {
            char ch = input.charAt(i);
            switch (ch) {
                case '{':
                case '[':
                case '(':
                    stack.push(ch);
                    break;
                case '}':
                case ']':
                case ')':
                    if (!stack.isEmpty()) {
                        char chx = stack.pop();
                        if ((ch == '}' && chx != '{') ||
                                (ch == ']' && chx != '[') ||
                                (ch == ')' && chx != '(')) {
                            System.out.println("解析异常:" + ch + "在位置" +i);
                        }
                    }else{
                        System.out.println("解析异常:" + ch + "在位置" +i);
                    }
                    break;
                default:
                    break;
            }
        }
        if (!stack.isEmpty()){
            System.out.println("字符串异常,遗失右分隔符");
        }
        System.out.println("解析正确");

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值