数据结构与算法之美笔记——栈

摘要:

栈(Stack)」是一种受到限制的「线性表数据结构」,有先进后出/后进先出的特点,栈这种数据结构在表达式计算和浏览器前进后退功能上都有使用。

这章节主要介绍栈这种数据结构,栈是一种受到限制的线性表数据结构,数据只能从一端插入和删除数据,虽然限制使栈失去了灵活性,但操作的可控性得到提高。

栈

顺序栈

栈可以使用数组或链表来实现,使用数组实现的栈称为「顺序栈」,使用链表实现的栈叫做「链式栈」,接下来使用数组实现一个栈。

public class ArrayStack {
    protected int size;
    protected int topIndex = 0;
    protected String[] stack;

    public ArrayStack(int size) {
        this.size = size;
        stack = new String[size];
    }

    public void push(String data) {
        if(topIndex == size) {return;}

        stack[topIndex] = data;
        ++topIndex;
    }

    public String pop() {
        String stackTop = stack[topIndex];
        --topIndex;
        return stackTop;
    }
}

如果使用数组实现一个栈,会在栈初始化的时候就固定了栈的大小,而用链表实现的栈就没有这样的问题,但是可以对数组使用动态扩容的策略构造一个动态扩容的栈。

public class ExpandArrayStack extends ArrayStack {
    public ExpandArrayStack(int size) {
        super(size);
    }

    @Override
    public void push(String data) {
        if(topIndex == size) {
            expandArray();
        }
        super.push(data);
    }

    private void expandArray() {
        size = size * 2;
        String[] newStack = new String[size];
        for(int i = 0; i < size / 2; i++) {
            newStack[i] = stack[i];
        }

        stack = newStack;
    }
}

可扩容的栈与顺序栈在出栈操作上并没有什么分别,只是在入栈时需要判断当前栈是否已满,如果已经栈已经满了就需要创建一个更大的栈,将原栈内的数据搬移至新的栈中,再将新的栈赋给原有栈,这样就完成了栈的扩容。

栈的应用

虽然栈操作受限,但也有对应的应用场景,当数据满足先进后出的特点时,便可以使用栈来实现,比如在表达式计算上。

对只有加减乘除四则运算这样较简单的表达式进行分析,当这样一个计算表达式 2 + 3 ∗ 6 − 9 2+3*6-9 2+369 出现在你眼前时,你可以很快速地计算出结果,但是对于计算机而言,识别这个表达式都存在一定困难,那如何利用栈来解决表达式解析和计算呢?

首先会定义两个栈,一个栈存放数字(以下简称栈 A),另一个存放运算符号(以下简称栈 B),对表达式进行解析时,当解析到数字时入栈栈 A,当解析到运算符号时需要判断栈 B 的情况,如果栈 B 为空或者此运算符比栈 B 的栈顶运算符运算级别高,便将运算符入栈,否则需要从栈 A 取出两个数字,从栈 B 取出一个运算符号进行计算,将计算结果入栈栈 A,再将栈 B 栈顶运算符号与解析到的符号比较级别。如此重复操作,直到解析完整个表达式,如果栈 B 不为空就按顺序将栈 B 中的符号取出进行计算,直到清空栈为止,清空栈计算出的结果就为此表达式的计算结果。

表达式的应用

浏览器的前进后退也可以利用栈来解决,也需要两个栈,一个栈存放当前页面和当前页面之前的页面(以下简称栈 C),栈顶元素就是当前访问页面,一个栈存放当前页面之后的页面(以下简称栈 D),当点击前进时将栈 D 的栈顶元素取出放入栈 C,浏览器后退时将栈 C 栈顶元素取出放入栈 D,如果此时访问了一个新的页面,将新页面放入栈 C,并且将栈 D 清空。

浏览器前进后退的应用


文章中如有问题欢迎留言指正
此章节关于顺序栈、链式栈等代码已经上传GitHub,可点击此处跳转查看。
数据结构与算法之美笔记系列将会做为我对王争老师此专栏的学习笔记,如想了解更多王争老师专栏的详情请到极客时间自行搜索。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值