数据结构与算法系列3之栈 与栈的使用场景

栈的定义

后进先出,先进后出,是一种操作受限的线性表,只允许在一端插入和删除数据。大多数使用栈的场景都可以使用数组或者链表进行代替,但是数组和链表暴露了太多操作的接口,看上去很灵活,但是对应的风险增大了,更加地不可控。

定容栈

即在创建的时候就指定一个栈的大小

创建一个定容栈

未使用范型

package com.pjh.Stack;
public class FixedCapacityStack {
    /*定义一个数组*/
    private  String[] a;
    /*定义一个大小*/
    private int N;
    /*有参构造方法*/
    public FixedCapacityStack(int n) {
       a=new String[n];
    }
    /*判断数组是否为空*/
    public boolean isEmpty(){
        return N==0;
    }
    /*返回数组的大小*/
    private int size(){
        return N;
    }
    /*出栈*/
    public String pop(){
        return a[--N];
    }
    /*入栈*/
    public void push(String item){
        a[N++]=item;
    }
}

使用范型

注意:由于某些历史与技术的原因创建范型数组是不被允许的

实现代码

package com.pjh.Stack;
public class FixedCapacityStack2<Item> {
    /*定义一个数组*/
    private Item a[];
    /*定义一个大小*/
    private int N;
    /*有参构造方法*/
    public FixedCapacityStack2(int n) {
        a=(Item[]) new Object[n];
    }
    /*判断数组是否为空*/
    public boolean isEmpty(){
        return N==0;
    }
    /*返回数组的大小*/
    private int size(){
        return N;
    }
    /*出栈*/
    public Item pop(){
        return a[--N];
    }
    /*入栈*/
    public void push(Item item){
        a[N++]=item;
    }
}

代码优化

问题1

问题概述

选择数组表示栈的内容必须预先估计栈的最大容量,在java中,数组一但创建其大小是无法改变的,因此栈使用的空间只能是这个最大容量的一部分。选择大容量的用例在栈为空或者几乎为空的时候会浪费大量的内存,例如,一个交易系统可能会涉及数十亿笔交易和数千个交易的集合。即使这种系统一般都会限制每笔交易只能出现在一个集合中,但用例必须保证所有的集合都有能力保存所有的交易,另一方面,如果集合变的比数组大,那么用例可能会溢出。因此我们需要一个方法来检测栈是不是已经满了,还有一个方法来对栈进行扩容,这个其实就是动态数组的思想

解决方案

isFull()方法判断栈是不是已经满了

 /*判满方法,只供内部方法调用*/
    private void isFull(){
        /*如果满了则调用数组扩容方法,扩容的倍数可以根据实际的需要调节*/
        if (N==a.length){
            resize();
        }
    }

resize()扩容方法

private void resize(){
        int newCapacity= (int) (a.length * 2);
        int lastCapacity=a.length;
        Item[] newArray =  (Item[]) new Object[newCapacity];
        for (int i = 0; i < lastCapacity; i++)
            newArray[i]=a[i];
        /*将a数组的首地址指向newArray数组*/
        a=newArray;
    }

问题2

问题概述2

如果我们在使用过程中将大量的数据进行出栈处理了,但是之前的数组空间很大,所以我们也需要动态的进行缩小栈的容量,以到达内存使用率的最大化

解决方案

在调用pop()出栈函数的时候,我们首先删除栈顶的元素,然后如果数组太大我们就将数组的长度减半

栈的使用场景

就拿我们平时使用的浏览器来举例,我们在同一个页面点击多个网页的时候,常常使用浏览器的退后与前进按钮,以回到前一个打开的页面和后一个打开的页面

在这里插入图片描述

比如我们在统一页面中先后打开了

taobao.com
jd.com
tx.com

当我们点击左箭头的的时候回到jd.com

当我们再点击右箭头的时候又回到taobao.com

这个操作就可以使用栈来实现
**
图解

在这里插入图片描述

当我们点击左箭头的的时候回到jd.com

在这里插入图片描述

当我们再点击右箭头的时候又回到taobao.com

在这里插入图片描述

类似的应用场景还有软件的撤销恢复功能

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/pjh88/article/details/114401963