栈的原理及数组方式实现

栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。

首先系统或者数据结构栈中数据内容的读取与插入(压入push和 弹出pop)是两回事!压入是增加数据,弹出是删除数据 ,这些操作只能从栈顶即最低地址作为约束的接口界面入手操作 ,但读取栈中的数据是随便的没有接口约束之说。很多人都误解这个理念从而对栈产生困惑。

栈顶指针指向的是下一个要插入的元素的位置。
可以简单地看一下图片(自己画的比较丑),结合下面的数组实现方式代码理解一下栈的原理
进栈及出栈流程
数组实现栈数据结构的功能code。

public class ArrayStack<T> {

    // 数组实现栈
    private Object[] arr;
    // 栈顶指针,指向下一个插入元素的位置
    private int top;
    // 初始化一个大小
    private final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
    // 当前栈的大小(数组中的元素的个数,可以用栈顶指针来代替size = top),为了分的清楚还是引入这个变量
    private int size;

    //两种初始化方式:指定初始化大小和不指定初始化大小
    public ArrayStack(int initSize) {
        if (initSize < 0) {
            throw new IllegalArgumentException("stack init size can't less than zero");
        }
        this.arr = new Object[initSize];
        // 栈中存储的数据的个数
        this.size = 0;
        // 初始化时栈顶指针指向数组0索引位置的
        this.top = 0;
    }

    // 使用无参构造默认数组初始大小16
    public ArrayStack() {
        this.arr = new Object[DEFAULT_INITIAL_CAPACITY];
        this.top = 0;
        this.size = 0;
    }


    /**
     * 入栈流程:
     * 若TOP≥n时,则给出溢出信息,作出错处理(进栈前首先检查栈是否已满,满则溢出;不满则作②);
     * 置TOP=TOP+1(栈指针加1,指向进栈地址);
     * S(TOP)=X,结束(X为新进栈的元素);
     * @param t
     */
    public boolean push(T t) {
        if (size >= arr.length) {
            throw new IllegalArgumentException("stack overflow exception");
        }
        // 新加入的元素放到栈顶并且栈顶指针上移动一位
        arr[top++] = t;
        // 每加入一个新的元素栈大小+1
        size++;
        // 添加成功返回true
        return true;
    }


    /**
     * 出栈流程:
     * 若TOP≤0,则给出下溢信息,作出错处理(退栈前先检查是否已为空栈, 空则下溢;不空则作②);
     * X=S(TOP),(退栈后的元素赋给X):
     * TOP=TOP-1,结束(栈指针减1,指向栈顶)。
     * @return
     */
    public boolean pop() {
        if (top <= 0) {
            throw new IllegalArgumentException("stack is empty");
        }
        // 出栈指针下移
        top--;
        // 栈大小减一
        size--;
        // 出栈完成返回true
        return true;
    }


    //查看目前栈顶数据
    public T getTop() {
        if (top == 0) {
            throw new IllegalArgumentException("stack is empty");
        }
        // 返回栈顶元素(arr[top - 1])
        return (T) arr[size - 1];
    }

    // 查看栈中任意位置上的元素
    public T get(int index){
        if(index < 0 || index >= size){
            throw new IllegalArgumentException("out of bound exception");
        }
        return (T) arr[index];
    }

    // 查看栈的大小
    public int size(){
        // size设置为方法可以避免用户随意修改栈的大小
        return size;
    }
}

写完代码之后可以简单测试一下功能是否与预期的相符。

class test {
    public static void main(String[] args) {
        // 指定初始化大小为3
        ArrayStack<Integer> arrayStack = new ArrayStack<>(3);
        // 入栈
        arrayStack.push(10);
        arrayStack.push(20);
        arrayStack.push(30);
//        arrayStack.push(30);  // (上溢出)添加第四个元素报出异常:stack overflow exception
        System.out.println(arrayStack.size());  // 3
        System.out.println(arrayStack.getTop());  // 30
        System.out.println(arrayStack.get(0));  // 10
//        System.out.println(arrayStack.get(3));  // 下标越界
        // 出栈
        arrayStack.pop();
        System.out.println(arrayStack.size());  // 2
        arrayStack.pop();
        arrayStack.pop();
//        arrayStack.pop();  // 栈中没有元素再进行出栈操作:stack is empty
        System.out.println(arrayStack.size()); // 空栈大小为0
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值