Stack源码分析


之前我们看过Vector,知道Vector是基于数组实现的,本文我们来看看Stack(栈)这种数据结构

栈是一种先进后出的数据结构,可以基于数组实现,也可以基于链表实现

java集合中的Stack是基于Vector实现的,对于Vector可以具体看Vector源码分析

public
class Stack<E> extends Vector<E> 

底层数据结构

因为是基于Vector实现,是Vector的子类,所以同样,Stack的底层数据结构是数组

public
class Stack<E> extends Vector<E> 

protected Object[] elementData;

构造方法

只有一个默认的无参构造方法,调用构造一个空栈

    public Stack() {
    }

进栈

进栈操作操作的数组的末端,数组的末端相当于栈顶

    public E push(E item) {
        addElement(item);

        return item;
    }

调用的是vector的添加元素的方法,默认是数组末端添加

    public synchronized void addElement(E obj) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = obj;
    }

获得栈顶元素

peek()方法是线程安全的,也使用到了同步关键字,通过数组下标直接定位到栈顶元素,从而获取

    public synchronized E peek() {
        int     len = size();

        if (len == 0)
            throw new EmptyStackException();
        //通过数组下标直接定位到栈顶元素    
        return elementAt(len - 1);
    }

    //返回当前数组元素个数,这是Vector的API,在这里是栈中元素个数
    public synchronized int size() {
        return elementCount;
    }

    //Vector的API,根据下标获取值
    public synchronized E elementAt(int index) {
        if (index >= elementCount) {
            throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
        }

        return elementData(index);
    }

出栈

也是调用Vector的API直接点根据下标删除栈顶元素

    public synchronized E pop() {
        E       obj;
        int     len = size();

        //获取栈顶元素,返回用
        obj = peek();
        //根据下标删除栈顶元素
        removeElementAt(len - 1);

        return obj;
    }

    //也是调用Vector的API直接点根据下标删除栈顶元素
    public synchronized void removeElementAt(int index) {
        modCount++;
        if (index >= elementCount) {
            throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                     elementCount);
        }
        else if (index < 0) {
            throw new ArrayIndexOutOfBoundsException(index);
        }
        int j = elementCount - index - 1;
        if (j > 0) {
            System.arraycopy(elementData, index + 1, elementData, index, j);
        }
        elementCount--;
        elementData[elementCount] = null; /* to let gc do its work */
    }

查询元素在栈中位置(下标)

    public synchronized int search(Object o) {
        //从后往前找,在这里可以看做从栈顶往栈底
        int i = lastIndexOf(o);

        if (i >= 0) {
            return size() - i;
        }
        return -1;
    }

    //第二个参数是查询的开始下标
    public synchronized int lastIndexOf(Object o) {
        return lastIndexOf(o, elementCount-1);
    }

    public synchronized int lastIndexOf(Object o, int index) {
        if (index >= elementCount)
            throw new IndexOutOfBoundsException(index + " >= "+ elementCount);

        if (o == null) {
            for (int i = index; i >= 0; i--)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = index; i >= 0; i--)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

上面就是jdk中Stack的源码,Stack在jdk中是基于顺序存储结构的数组实现的,也可以基于双向链表的LinkedList实现,下边看看如何用LinkedList实现栈

linkedList实现栈

底层数据结构

    List<Integer> list;

    /** Initialize your data structure here. */
    public MyStack() {
       list = new LinkedList<>();
    }

进栈

进栈操作中,Vector操作的是数组末端,那么linkedList也很类似,操作的是尾节点,链表末端就是栈顶

    /** Push element x onto stack. */
    public void push(int x) {
        list.add(x);
    }

    public boolean add(E e) {
        linkLast(e);
        return true;
    }

出栈

    public int pop() {
       int length = list.size();
       return list.remove(length);
    }
    
    //找到相关节点后,删除节点,解除链接关系
    public E remove(int index) {
        checkElementIndex(index);
        return unlink(node(index));
    }

获得栈顶元素

    public int top() {
        int length = list.size();
        return list.get(length);
    }

    //通过下标找到相关节点后获取节点值
    public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }

是否是空栈

    public boolean empty() {
        return list.isEmpty();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值