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

article/2023/6/4 16:14:46

文章目录

  • 1.什么是栈?
  • 2.栈的应用场景
  • 3.栈的具体实现
    • 3.1 基于简单数组的实现
    • 3.2 动态数组的实现
    • 3.3 链表的实现
    • 3.4 Java动态数组实现栈结构
  • 4 项目地址

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<>();@Testpublic 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


https://www.dgrt.cn/a/2109918.html

相关文章

应用桌面图标快捷方式找不到了 用命令方式找到应用并创建快捷方式

这个方式可以创建任何桌面图标 1、按住 “win” R 弹出输入系统指令页面&#xff0c;如图&#xff1a; 在这一步输入指令 “%windir%\explorer.exe shell:::{4234d49b-0245-4df3-b780-3893943456e1}” 按回车 此时出现如下界面&#xff0c;找到你需要的应用然后右键创建桌面图…

配置代理服务器

配置代理——方式一 俩台服务都准备完成 现在主要用来发起请求的第三方库都是axios 先下载引入axios 出现跨域问题&#xff0c;注意的一点是服务器是拿到数据&#xff0c;但是并没有返回 解决跨域问题 1.cors 这要麻烦后端人员&#xff0c;就是在响应数据时设置一个特殊的响…

二叉树概念及基本功能实现

目录 一、二叉树概述 二、代码实现一棵二叉树&#xff1a; 三、二叉树的遍历 四、二叉树遍历代码实现 1.先序遍历&#xff1a; 2.中序遍历&#xff1a; 3.后序遍历&#xff1a; 4.层次遍历&#xff08;一层一层遍历&#xff09;&#xff1a; 5.main方法执行 五、二叉…

h5与APP交互

两端交互安卓&#xff1a;https://github.com/lzyzsd/JsBridge IOS&#xff1a;https://github.com/marcuswestin/WebViewJavascriptBridge 两者一起用的话会起冲突&#xff0c;需要判断一下是什么终端&#xff0c;然后分别调用&#xff0c; var u navigator.userAgent; var i…

ADV-216 5-3日历

问题描述已知2007年1月1日为星期一。设计一函数按照下述格式打印2007年以后&#xff08;含&#xff09;某年某月的日历&#xff0c;2007年以前的拒绝打印。为完成此函数&#xff0c;设计必要的辅助函数也是必要的。样例输入一个满足题目要求的输入范例。例&#xff1a;2050 3样…

openfeign 全局日志打印

文章目录[TOC](文章目录)前言一、openfeign 集成二、配置使用1.全局feign 配置2.yml feign配置总结前言 feign 相对于 resttemplate 来说不仅兼具他的功能,而且比他更强大,所以当项目为springcloud架构之后,无论是服务之间的调用,还是其他的http调用,都应该统一用feign处理; 如…

动态代理和AOP人(面向切面编程)

1.什么是动态代理 1&#xff09;动态代理就是利用JDK的API动态的在内存中构建代理对象&#xff0c;因此&#xff0c;动态代理也叫做JDK代理&#xff0c;或者接口代理&#xff0c;在动态代理中&#xff0c;代理对象不需要实现接口&#xff0c;但是被代理对象还是需要实现对象的…

ADV-231-扑克排序

问题描述扑克牌排序&#xff1a;构造扑克牌数组&#xff0c;对扑克牌进行排序。排序原则如下&#xff1a;数字从小到大是2-10、J、Q、K和A&#xff0c;花色从小到大是方块&#xff08;diamond&#xff09;、梅花&#xff08;club&#xff09;、红桃&#xff08;heart&#xff0…