Java数据结构 - 栈与MyStack

Java数据结构 - 栈

一、什么是栈

栈属于线性表的一种特殊结构,栈中的元素被限制为只能从表的一端进出,这一端称之为栈顶,另一端称为栈底,元素进出的顺序遵循先进后出(First In Last Out),或后进先出(Last In First Out)。

压栈(push):将元素插入表中的操作叫做进栈/压栈/入栈,插入元素在栈顶。

出栈(pop):将元素从表中删除的操作叫出栈/弹栈,删除元素在栈顶。

在这里插入图片描述

二、模拟实现容器类MyStack

1. 栈的顺序存储结构

在这里插入图片描述

import java.util.Arrays;

/**
 * 模拟实现栈容器类  ——— 使用数组存储结构的方式
 */
public class MyStack<E> {

    //使用数组来存储栈元素
    private Object[] elementData;
    //默认栈容量大小为10
    private static final int DEFAULT_CAPACITY = 10;
    //实际栈容量大小
    private int size = 0;

    /**
     * 创建一个默认初始容量大小的栈对象
     */
    public MyStack(){
        this.elementData = new Object[DEFAULT_CAPACITY];
    }

    /**
     * 创建一个指定初始容量的栈对象
     * @param initialCapacity 指定初始容量
     */
    public MyStack(int initialCapacity){
        this.elementData = new Object[initialCapacity];
    }

    /**
     * 将元素e入栈并返回
     * @param e 元素对象
     * @return e
     */
    public E push(E e){
        ensureCapacity();
        elementData[size++] = e;
        return e;
    }

    //检测当前栈容量大小,如果已满则进行扩容,扩容大小为原数组长度的2倍
    private void ensureCapacity(){
        if(size == elementData.length){
            int oldLen = elementData.length;;

            //手动扩容
//            Object[] newElementData = new Object[oldLen * 2];
//            for(int i = 0; i < oldLen; i++){
//                newElementData[i] = elementData[i];
//            }
//            elementData = newElementData;

            //使用Arrays.copyOf()
            elementData = Arrays.copyOf(elementData,oldLen * 2);
        }
    }

    /**
     * 将当前栈顶的元素出栈并返回,如果栈为空,抛出异常
     * @return 栈顶元素
     */
    @SuppressWarnings("unchecked")
    public E pop(){
        if(isEmpty()){
            throw new EmptyStackException("当前栈为空!");
        }else{
            return (E) elementData[--size];
        }
    }

    /**
     * @return 当前栈是否为空
     */
    public boolean isEmpty(){
        return size == 0;
    }

    /**
     * 返回当前栈顶的元素,如果栈为空,抛出异常
     * @return 栈顶元素
     */
    @SuppressWarnings("unchecked")
    public E peek(){
        if(isEmpty()){
            throw new EmptyStackException("当前栈为空!");
        }else{
            return (E)elementData[size-1];
        }
    }

    /**
     * @return 返回当前栈的元素个数
     */
    public int size(){
        return size;
    }
}

2. 栈的链式存储结构

在这里插入图片描述

/**
 * 模拟实现栈容器类 ——— 使用单链表存储结构的方式
 */
public class MyStack2<E> {
    //内部结点类 - 存放栈的元素
    private static class Node<E>{
        E item;
        Node<E> next;

        Node(E element){
            this.item = element;
        }

        Node(E element,Node<E> next){
            this.item = element;
            this.next = next;
        }
    }

    private Node<E> head; //记录链表头结点
    private int size; //栈中元素个数
    
    //创建一个栈对象
    public MyStack2(){
    }
    
    /**
     * 将元素e入栈并返回
     * @param element 元素对象
     * @return e
     */
    public E push(E element){
        //使用头插法
        Node<E> newNode = new Node<>(element);
        newNode.next = head;
        head = newNode;
        size++;
        return element;
    }

    /**
     * 将栈顶元素出栈并返回,如果栈为空,则抛出异常
     * @return 栈顶元素
     */
    public E pop(){
        if(isEmpty()){
            throw new EmptyStackException("当前栈为空!");
        }else{
            E popped = head.item;
            head = head.next;
            size--;
            return popped;
        }
    }

    /**
     * 就栈顶元素返回,如果栈为空,则抛出异常
     * @return 栈顶元素
     */
    public E peek(){
        if(isEmpty()){
            throw new EmptyStackException("当前栈为空!");
        }else{
            return head.item;
        }
    }

    /**
     * @return 返回当前栈中的元素个数
     */
    public int size(){
        return size;
    }

    /**
     * @return 当前栈是否为空
     */
    public boolean isEmpty(){
        return head == null;
    }
}

三、Java集合框架中的Stack类

在这里插入图片描述

在这里插入图片描述

  • Java官方提供的Stack类是继承于Vector容器类的,Vector是最早的对象容器类,于ArrayList相比是线程安全的,但是效率低。

  • 查阅源码可以看到Stack类中并没有字段属性,而是使用的继承于Vector的elementData。且Stack类中的成员方法也是在Vector提供的方法上进行了封装。
    在这里插入图片描述

四、概念区分

栈、虚拟机栈、栈帧有什么区别呢?

栈:栈是数据结构中一种特殊的线性表,栈中元素只能从栈顶进出,元素遵循先进后出的原则。

虚拟机栈:是JVM的一块内存空间

栈帧:是在调用方法的过程中,在Java虚拟机栈上开辟的一块内存。


文章为本人独立编写,难免会有错误之处。
如发现有误,恳请评论提出!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值