java数据结构——栈

说到栈,我们浮现在脑海中的肯定是后进先出(LIFO),先进入的数据被压入栈底,最近的数据在栈顶,当需要读取数据的时候,从栈顶弹出数据。
插入一般称为进栈(PUSH),删除则称为退栈(POP)。以羽毛球筒为例,羽毛球筒就是一个栈,刚开始羽毛球筒是空的,也就是空栈,然后我们一个一个放入羽毛球,也就是一个一个push进栈,当我们需要使用羽毛球的时候,从筒里面拿,也就是pop出栈,但是第一个拿到的羽毛球是我们最后放进去的。
push图示
在这里插入图片描述
pop图示
在这里插入图片描述

下面是我用数组实现的一个栈模型,代码如下:


public class MyStack {

    private final int[] arr;

    private final int size;

    private int top;

    public MyStack(int size){
        if(size<=0){
            this.size = 0;
            arr = null;
            System.out.println("参数错误");
        }else{
            this.size = size;
            arr = new int[this.size];
            top = -1;
        }
    }

    public void push(int data){
        if(top < size-1){
            arr[top+1] = data;
            top++;
        }else{
            System.out.println("满了");
        }
    }

    public int pop(){
        if(top == 0){
            System.out.println("栈中空的");
            return -1;
        }else{
            top--;
            return arr[top+1];
        }
    }

    public int peek(){
        if(top == 0){
            System.out.println("栈中空的");
            return -1;
        }else{
            return arr[top];
        }
    }

    public boolean isEmpty(){
        return top == 0;
    }

    public boolean isFull(){
        return top == (size-1);
    }

    public static void main(String[] args) {
        MyStack myStack = new MyStack(4);

        myStack.push(1);
        myStack.push(2);
        myStack.push(3);
        myStack.push(4);
        myStack.push(5);

        System.out.println(myStack.peek());
        System.out.println(myStack.pop());
        System.out.println(myStack.peek());
    }
}

上面的代码内部使用了数组存放数据,size表示栈的最大容量,top用来指示栈顶的位置。通过构造方法规定了该栈的容量,push()方法是向栈中压入元素,指向栈顶的变量top加一,使它指向原顶端数据项上面的一个位置,并在这个位置上存储一个数据。pop()方法返回top变量指向的元素,然后将top变量减一,便移除了数据项。

但是上面的栈由于是固定大小,不支持扩容,而且里面只能放int,那么就需要进行一些功能的扩充,代码如下:

public class GrowableArrayStack {

    private static final int DEFAULT_CAPACITY = 5;

    private Object[] elementData;

    private int top;

    private int size;

    private static int factor = 2;

    public GrowableArrayStack(){
        elementData = new Object[DEFAULT_CAPACITY];
        top = -1;
        size = DEFAULT_CAPACITY;
    }

    public GrowableArrayStack(int size) throws IllegalArgumentException{
        if(size <= 0){
            throw new IllegalArgumentException("容量应该大于0 : "+size);
        }
        elementData = new Object[size];
        top = -1;
        this.size = size;
    }

    public void push(Object obj){
        isGrow(top+1);
        elementData[++top] = obj;
    }

    public Object pop(){
        Object object = peek();
        remove(top);
        return object;
    }

    public boolean isEmpty(){
        return (top==-1);
    }

    public Object peek(){
        if(isEmpty()){
            throw new EmptyStackException();
        }
        return elementData[top];
    }

    public void remove(int top){
        elementData[top] = null;
        this.top--;
    }

/*扩容*/
    private void isGrow(int index){
        if(index>size){
            int newCapacity = 0;
            if(size * factor > Integer.MAX_VALUE){
                newCapacity = Integer.MAX_VALUE;
            }else{
                newCapacity = size*factor;
            }
            elementData = Arrays.copyOf(elementData,newCapacity);
        }
    }
}

下面我们需要测试一下,当然不是简单的测试,我们可以用我们上面的代码完成一些简单的功能。

字符串的reverse

    private static void reverseString(){
        String string = "abcdef";
        char[] chars = string.toCharArray();
        GrowableArrayStack growableArrayStack = new GrowableArrayStack(chars.length);
        for(char a : chars){
            growableArrayStack.push(a);
        }

        String reverse = "";
        for (int i = 0; i < chars.length; i++) {
            reverse+=growableArrayStack.pop();
        }
        System.out.println(reverse);
    }

输出 fedcba

字符合法性
写过xml标签或者html标签的,我们都知道<必须和最近的>进行匹配,[ 也必须和最近的 ] 进行匹配。比如:<abc[123]abc>这是符号相匹配的,如果是 <abc[123>abc] 那就是不匹配的。对于 12<a[b{c}]>,我们分析在栈中的数据:遇到匹配正确的就消除

    private static void testValid(){
        String str = "12<ha[bb{f}]>{";
        char[] chars = str.toCharArray();
        GrowableArrayStack growableArrayStack = new GrowableArrayStack(6);
        for(char a : chars){
            switch (a){
                case '<':
                case '[':
                case '{':
                    growableArrayStack.push(a);
                    break;
                case '>':
                    if('<' == (char)(growableArrayStack.peek())){
                        growableArrayStack.pop();
                    }else {
                        growableArrayStack.push(a);
                    }
                    break;
                case ']':
                    if('[' == (char)(growableArrayStack.peek())){
                        growableArrayStack.pop();
                    }else {
                        growableArrayStack.push(a);
                    }
                    break;
                case '}':
                    if('{' == (char)(growableArrayStack.peek())){
                        growableArrayStack.pop();
                    }else {
                        growableArrayStack.push(a);
                    }
                    break;
                default:
                    break;
            }
        }

        if(growableArrayStack.isEmpty()){
            System.out.println("合法");
        }else{
            System.out.println("非法");
        }
    }

输出 合法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值