栈是一种运算受限的线性表,其限制是仅允许在表的一端进行插入和删除运算。它的一端是栈顶,另一端是栈底,元素唯一的进出口是栈顶,它的特点是先进栈的元素后出栈(先进后出);

java中栈的实现有两种方式,数组和链表

数组实现的栈

底层由数组实现,通过操作数组来实现元素的存入和取出,使用top来标识栈顶元素位置。

public class ArrayStack<E> {

    /**
     * 用于存储元素的数组
     */
    private Object[] elements;

    /**
     * 用于标识栈顶元素的位置
     */
    private int top = -1;

    /**
     * 初始化构造方法,实例化一个大小为10的Object数组
     */
    public ArrayStack() {
        elements = new Object[10];
    }

    /**
     * 压栈,将元素存入Object数组
     * @param var
     * @return
     */
    public E push(E var) {
        //在存入元素之前先检查当前数组空间是否足够
        this.resize();
        //先将top+1,然后在数组top+1位置上放入元素
        elements[++top] = var;
        //返回存入的元素
        return var;
    }

    /**
     * 出栈
     * @return
     */
    public synchronized E pop() {
        //调用peek方法获取到栈顶元素
        Object top = this.peek();
        //将栈顶元素设置为null,然后将top-1
        this.elements[this.top--] = null;
        //返回出栈的栈顶元素
        return (E)top;
    }

    /**
     * 查看栈顶元素
     * @return
     */
    public synchronized E peek() {
        //获取到当前栈中元素个数
        int var1 = this.size();
        
        if (var1 == 0) {
            //如果当前栈中元素个数为0,则抛错栈为空
            throw new RuntimeException("栈为空");
        } else {
            //否则返回栈顶元素
            return (E)this.elements[this.top];
        }
    }

    /**
     * 判断当前栈是否为空
     * @return
     */
    public boolean empty() {
        //如果当前栈元素个数为0,则为空
        return this.size() == 0;
    }

    /**
     * 获取当前栈元素个数
     * @return
     */
    private int size(){
        //栈顶位置+1 = 当前元素个数
        return this.top+1;
    }

    /**
     * 重新设置当前数组大小
     */
    private void resize(){
        //如果当前栈元素个数大于等于数组大小
        if(this.size() >= this.elements.length){
            //新建一个原有数组两倍大小的数组
            Object[] temp = new Object[this.elements.length*2];
            //将原有数组复制到新数组中
            System.arraycopy(this.elements,0,temp,0,this.elements.length);
            //再将当前数组引用替换成新数组
            this.elements = temp;
        }
    }

    public static void main(String[] args) {
        ArrayStack<String> arrayStack = new ArrayStack<String>();
        arrayStack.push("1");
        arrayStack.push("2");
        arrayStack.push("3");
        arrayStack.push("4");
        arrayStack.push("5");
        arrayStack.push("6");
        arrayStack.push("7");
        arrayStack.push("8");
        arrayStack.push("9");
        arrayStack.push("10");
        arrayStack.push("11");

        System.out.println("栈的大小"+arrayStack.size());
        System.out.println("栈的顶部元素:"+arrayStack.peek());
        System.out.println("栈的大小"+arrayStack.size());
        System.out.println("栈弹出的顶层元素:"+arrayStack.pop());
        System.out.println("栈的顶部元素:"+arrayStack.peek());
        System.out.println("栈是否为空:"+arrayStack.empty());
    }



}

运行结果

 

链表实现的栈

除了数组可以实现栈数据结构外,链表也可以实现栈,成员变量top(存储栈顶节点)size(当前栈元素个数),LinkedStack中定义内部静态私有类LinkedStackNode,LinkedStackNode中存储前一节点、后一节点、元素。

package stack;

public class LinkedStack<E> {

    //标识栈顶节点
    private LinkedStack.LinkedStackNode<E> top;
    //当前栈元素个数
    private int size;

    /**
     * 压栈,将元素存入Object数组
     * @param var
     * @return
     */
    public E push(E var) {
        if(this.size() == 0){
            //如果当前栈元素个数为0,说明当前的栈顶为null,新建节点
            LinkedStack.LinkedStackNode<E> temp = new LinkedStack.LinkedStackNode<E>(null,var,null);
            //栈顶为temp
            this.top = temp;
        }else{
            //否则说明存在top,新建的节点要以top为前一节点
            LinkedStack.LinkedStackNode<E> temp = new LinkedStack.LinkedStackNode<E>(this.top,var,null);
            //栈顶节点的next设置为temp,建立链表关联
            this.top.next = temp;
            //将新建的temp节点作为栈顶节点
            this.top = temp;
        }
        //当前栈元素个数+1
        this.size++;
        return var;
    }

    /**
     * 出栈
     * @return
     */
    public synchronized E pop() {
        //调用peek方法获取到栈顶元素
        E currTop = this.peek();
        //如果当前栈中只有一个元素
        if(this.size() == 1){
            //那么弹出后top为null
            this.top = null;
        }else{
            //否则将当前栈顶元素top的前一节点的next修改为null
            this.top.prev.next = null;
            //栈顶节点等于栈顶节点的prev,这里直接通过修改上一节点的next来移除节点
            this.top = this.top.prev;
        }

        //返回出栈的栈顶元素
        this.size--;
        return currTop;
    }

    /**
     * 查看栈顶元素
     * @return
     */
    public synchronized E peek() {
        //获取到当前栈中元素个数
        int var1 = this.size();

        if (var1 == 0) {
            //如果当前栈中元素个数为0,则抛错栈为空
            throw new RuntimeException("栈为空");
        } else {
            //否则返回栈顶元素
            return this.top.item;
        }
    }

    /**
     * 判断当前栈是否为空
     * @return
     */
    public boolean empty() {
        //如果当前栈元素个数为0,则为空
        return this.size() == 0;
    }

    /**
     * 获取当前栈元素个数
     * @return
     */
    private int size(){
        return this.size;
    }

    private static class LinkedStackNode<E>{
        //元素值
        E item;
        //当前节点的的下一节点
        LinkedStack.LinkedStackNode<E> next;
        //当前节点的上一节点
        LinkedStack.LinkedStackNode<E> prev;
        public LinkedStackNode(LinkedStackNode<E> prev,E item, LinkedStackNode<E> next) {
            this.prev = prev;
            this.item = item;
            this.next = next;
        }
    }

    public static void main(String[] args) {
        LinkedStack linkedStack = new LinkedStack();
        linkedStack.push("1");
        linkedStack.push("2");
        linkedStack.push("3");

        System.out.println("栈的大小"+linkedStack.size());
        System.out.println("栈的顶部元素:"+linkedStack.peek());
        System.out.println("栈的大小"+linkedStack.size());
        System.out.println("栈弹出的顶层元素:"+linkedStack.pop());
        System.out.println("栈的顶部元素:"+linkedStack.peek());
        System.out.println("栈是否为空:"+linkedStack.empty());
        System.out.println("栈弹出的顶层元素:"+linkedStack.pop());
        System.out.println("栈弹出的顶层元素:"+linkedStack.pop());
        linkedStack.push("4");
        linkedStack.push("5");
        System.out.println("栈弹出的顶层元素:"+linkedStack.pop());
        System.out.println("栈弹出的顶层元素:"+linkedStack.pop());
    }
}

运行结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值