5.1 栈Stack基于动态数组的Java实现

1.什么是栈?

栈是一个有序的线性表,只能在栈顶进行操作插入和删除操作。所以也叫先进后出表。

2.栈的应用场景

  • 符号匹配
  • 中缀表达式转换为后缀表达式
  • 计算后缀表达式
  • 实现函数调用
  • 求范围误差
  • 网页浏览器中已访问页面的历史纪录
  • 文本编辑器中的撤销序列
  • 作为算法辅助数据结构(二叉树的非递归遍历)

3.栈的具体实现

3.1 基于简单数组的实现

顾名思义,就是用数组实现栈的应用

性能表:

操作时间复杂度空间复杂度
push()O(1)O(n)
pop()O(1)O(1)
size()O(1)O(1)
isEmpty()O(1)O(1)
isFull()O(1)O(1)
deleteStack()O(1)O(1)

3.2 动态数组的实现

它其实就是在简单数组基础上实现重复倍增来实现的:
以上面的简单数组实现为基础,增加一个倍增方法:

    /**
     * 栈空间扩增方法
     */
    private void doubleStack() {
        int[] newArray = new int[capacity*2];
        System.arraycopy(array,0,newArray,0,capacity);
        capacity = capacity*2;
        array = newArray;
    }

性能表:

操作时间复杂度空间复杂度
push()O(1)O(n)
pop()O(1)O(1)
size()O(1)O(1)
isEmpty()O(1)O(1)
isFull()O(1)O(1)
deleteStack()O(1)O(1)

3.3 链表的实现

使用链表实现栈,通过在链表的表头插入元素的方式实现push,删除链表的表头节点实现pop.
但,使用它还需要实现节点的构造,相比数组麻烦些,而且链表不太符合栈的顺序特性,

且它的性能表如下:

操作时间复杂度空间复杂度
push()O(1)O(n)
pop()O(1)O(1)
size()O(1)O(1)
isEmpty()O(1)O(1)
isFull()O(1)O(1)
deleteStack()O(n)O(1)

相比之下它的deleteStack复杂度比动态数组大。所以推荐使用动态数组实现栈。

3.4 Java动态数组实现栈结构

package course.p5_stack;

/**
 * 栈的基础实现
 * 栈比较适合使用数组实现,因为使用数组实现栈的push,pop的时间复杂度都为O(1),且操作简单
 */
public class ArrayStack {

    /**
     * 存储栈顶元素的索引
     */
    private int top;

    /**
     * 栈的空间大小,默认起始为10
     */
    private int capacity = 10;

    /**
     * 存储栈元素的数组
     */
    private int[] array;

    /**
     * 无参构造方法
     */
    public ArrayStack() {
        array = new int[capacity];
        top = -1;
    }

    /**
     * 定义大小构造方法
     * @param a 定义栈的大小
     */
    public ArrayStack(int a) {
        capacity = a;
        array = new int[a];
        top = -1;
    }

    /**
     * 判断此栈是否为空
     * @return true--空 false--不空
     */
    public boolean isEmpty() {
        return top == -1;
    }

    /**
     * 判断栈是否已满
     * @return
     */
    public boolean isStackFull() {
        return top == capacity-1;
    }

    /**
     * 将数据压入栈中
     * @param data
     */
    public void push(int data) {
        if(isStackFull()) {
            doubleStack();
        }
        array[++top] = data;
    }

    /**
     * 弹出栈顶元素
     * @return
     */
    public int pop() {
        if(isEmpty()) {
            System.out.println("Stack is Empty!");
            return -1;
        }
        else{
            return array[top--];
        }
    }

    /**
     * 删除栈
     */
    public void deleteStack() {
        top = -1;
        array = null;
        capacity = 0;
    }

    /**
     * 栈空间扩增方法
     */
    private void doubleStack() {
        int[] newArray = new int[capacity*2];
        System.arraycopy(array,0,newArray,0,capacity);
        capacity = capacity*2;
        array = newArray;
    }
}

测试方法编写:

package course.p5_stack;

import org.junit.Assert;
import org.junit.Test;

import java.util.Optional;
import java.util.Random;
import java.util.Stack;

public class StackTest {

    private final Stack<Integer> stackRight = new Stack<>();

    @Test
    public void stackTest(){
        ArrayStack stack = new ArrayStack();
        for (int i=0;i<1000;i++){
            boolean active = new Random().nextBoolean();
            if(active){
                stack.push(i);
                stackRight.push(i);
            }else {
                Assert.assertEquals(stackRight.isEmpty(),stack.isEmpty());
                if(!stackRight.isEmpty()){
                    Assert.assertEquals(Optional.ofNullable(stackRight.pop()),Optional.ofNullable(stack.pop()));
                }
            }
        }
    }

}

运行结果:(没有任何报错,测试通过)

Process finished with exit code 0

4 项目地址

https://gitee.com/yan-jiadou/algorithm-study/blob/master/algorithmStudy/src/main/java/course/p5_stack/StackTest.java

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小牧之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值