1.栈的介绍
栈是限制插入和删除只能在一个位置上进行的线性表。其中,允许插入和删除的一端位于表的末端,叫做栈顶(top),不允许插入和删除的另一端叫做栈底(bottom)。对栈的基本操作有 PUSH(压栈)和 POP (出栈),前者相当于表的插入操作(向栈顶插入一个元素),后者则是删除操作(删除一个栈顶元素)。栈是一种后进先出(LIFO)的数据结构,最先被删除的是最近压栈的元素。


弹栈:

栈实现
由于栈是一个表,因此任何实现表的方法都可以用来实现栈。主要有两种方式,链表实现和数组实现。
链表实现栈
可以使用单链表来实现栈。通过在表顶端插入一个元素来实现 PUSH,通过删除表顶端元素来实现 POP。使用链表方式实现的栈又叫动态栈。动态栈有链表的部分特性,即元素与元素之间在物理存储上可以不连续,但是功能有些受限制,动态栈只能在栈顶处进行插入和删除操作,不能在栈尾或栈中间进行插入和删除操作。
数组实现栈
栈也可以用数组来实现。使用数组方式实现的栈叫静态栈。
2.栈的应用场景

3.栈的快速入门
习题1:使用数组来模拟栈的使用

ArrayStack类
- package stack;
-
- public class ArrayStack {
-
- //栈的大小
- private int maxStack;
-
- //数组用来模拟栈
- private int[] stack;
-
- //表示栈顶的所在的位置,默认情况下没有数据使用-1
- private int top=-1;
-
- //有参构造
- public ArrayStack(int maxStack){
-
- this.maxStack=maxStack;
- stack=new int[maxStack];
- }
-
- //判断栈是否是空栈
- public boolean isFull(){
- return this.top==maxStack-1;
- }
-
- //判断栈是否是空栈
- public boolean isEmpty(){
- return this.top==-1;
- }
-
- //压栈
- public void push(int val){
- //是否已经栈满
- if(isFull()){
- throw new RuntimeException("此栈已满");
- }
- top++;
- stack[top]=val;
- }
-
- //弹栈
- public int pop(){
- if (isEmpty()){
- throw new RuntimeException("空栈,未找到数据!");
- }
- int value=stack[top];
- top--;
- return value;
- }
-
- //查看栈中所有的元素
- public void list(){
- //是否是空栈
- if (isEmpty()){
- throw new RuntimeException("空栈,未找到数据!");
- }
- for (int i=0;i
- System.out.printf("stack[%d]=%d\n", i ,stack[i]);
- }
- }
-
- //栈中元素存在的个数
- public int length(){
- return this.top+1;
- }
- }
习题2:回文数
回文: 一个单词、短语或数字,从前往后写和从后往前写都是一样的。比如,单词“dad”、“racecar”就是回文;如果忽略空格和 标点符号,下面这个句子也是回文,“A man, a plan, a canal: Panama”, 数字1001 也是回文。
思路:使用栈,可以轻松判断一个字符串是否是回文。我们将拿到的字符串的每个字符按从左至右的顺序压入栈。当字符串中的字符都入栈后,栈内就保存了一个反转后的字符串,最后的字符在栈顶,第一个字符在栈底。
Test类
- package stack;
-
- import java.util.Arrays;
-
- public class Test {
- public static void main(String[] args) {
-
- /**
- * 回文数据
- * 回文:aba racecar 回文就是压栈字符串顺序和出栈字符串顺序相等。
- * 需求:通过上面数组模拟栈,判断字符串是否是一个回文数据
- */
- System.out.println(detecation("aba"));
-
- }
-
- public static boolean detecation(String val){
- //初始化栈对象
- ArrayStack arrayStack=new ArrayStack(10);
-
- //获取字符串长度
- int length = val.length();
- //把字符串数据逐次获取字符压栈到数组中
- for (int i=0;i
- arrayStack.push(val.charAt(i));
- }
-
- //把字符串的数据逐次弹出
- String newVal="";
- int length1=arrayStack.length();
- for (int i=0;i
- //是否是一个空栈
- if (!arrayStack.isEmpty()){
- char pop= (char) arrayStack.pop();
- newVal+=pop;
- }
- }
- if (val.equals(newVal)){
- return true;
- }
- return false;
- }
-
-
-
-
- }
测试结果

4.栈实现计算器

首先在ArrayStack类中编写测试类所需要的方法
ArrayStack类
- package stack;
-
- public class ArrayStack {
-
- //栈的大小
- private int maxStack;
-
- //数组用来模拟栈
- private int[] stack;
-
- //表示栈顶的所在的位置,默认情况下没有数据使用-1
- private int top=-1;
-
- //有参构造
- public ArrayStack(int maxStack){
-
- this.maxStack=maxStack;
- stack=new int[maxStack];
- }
-
- //判断栈是否是空栈
- public boolean isFull(){
- return this.top==maxStack-1;
- }
-
- //判断栈是否是空栈
- public boolean isEmpty(){
- return this.top==-1;
- }
-
- //压栈
- public void push(int val){
- //是否已经栈满
- if(isFull()){
- throw new RuntimeException("此栈已满");
- }
- top++;
- stack[top]=val;
- }
-
- //弹栈
- public int pop(){
- if (isEmpty()){
- throw new RuntimeException("空栈,未找到数据!");
- }
- int value=stack[top];
- top--;
- return value;
- }
-
- //查看栈中所有的元素
- public void list(){
- //是否是空栈
- if (isEmpty()){
- throw new RuntimeException("空栈,未找到数据!");
- }
- for (int i=0;i
- System.out.printf("stack[%d]=%d\n", i ,stack[i]);
- }
- }
-
- //栈中元素存在的个数
- public int length(){
- return this.top+1;
- }
-
-
- //判断是否是一个运算符+ - * |
- public boolean isOper(char v){
- return v=='+' || v=='-' || v=='*' || v=='/';
- }
-
- //判断优先符的优先级,用数字表示优先级的大小,数字越大优先级越大
- public int priority(int oper){
- if (oper=='*' || oper=='/'){
- return 1;
- }else if (oper=='+' || oper=='-'){
- return 0;
- }else {
- return -1;
- }
- }
-
-
- //获取栈的栈顶数据
- public int peek(){
- return this.stack[top];
- }
-
- //获取栈的容量
- public int stackLength(){
- return this.stack.length;
- }
-
- //计算两个数进行运算后的结果(出栈时是先进后出)
- public int calculate(int num1,int num2,int oper){
- //计算结果
- int result=0;
- switch (oper){
- case '+':
- result = num1+num2;
- break;
- case '-':
- result= num2-num1;
- break;
- case '*':
- result=num1*num2;
- break;
- case '/':
- result=num2/num1;
- break;
- default:
- break;
- }
- return result;
- }
-
-
- }
Test2测试类
- package stack;
-
- public class Test2 {
- public static void main(String[] args) {
- String str="4+3*2-1";
-
- ArrayStack numStack=new ArrayStack(10);
- ArrayStack symbolStack=new ArrayStack(10);
-
- int temp1=0;
- int temp2=0;
- int symbolChar=0;
- int result=0;
- //获取字符串的长度
- int length = str.length();
-
- String values="";
- for (int i=0;i
- char c = str.charAt(i);
- //判断是否是一个运算符
- if (symbolStack.isOper(c)){
- //如果不是一个空的符号栈
- if (!symbolStack.isEmpty()){
- //比较运算符的优先级
- if (symbolStack.priority(c)
- /**
- * 1.去符号栈中获取栈顶的符号
- * 2.去数字栈中获取两个数字
- */
- temp1 = numStack.pop();
- temp2=numStack.pop();
- symbolChar = symbolStack.pop();
- result=numStack.calculate(temp1,temp2,symbolChar);
-
- //把运算结果再次放入数字栈中
- numStack.push(result);
-
- //把当前符号压入符号栈中
- symbolStack.push(c);
- }else {
- symbolStack.push(c);
- }
- }else {
- //如果是空字符栈,将运算符直接压栈
- symbolStack.push(c);
- }
- }else {
- values+=c;
-
- if (i==length-1){
- numStack.push(Integer.parseInt(values));
- }else {
- char c1 = str.substring(i + 1, i + 2).charAt(0);
- if (symbolStack.isOper(c1)){
- numStack.push(Integer.parseInt(values));
- values="";
- }
- }
- }
- }
-
- while (true){
- if (symbolStack.isEmpty()){
- break;
- }
- temp1=numStack.pop();
- temp2=numStack.pop();
-
- symbolChar=symbolStack.pop();
-
- result=numStack.calculate(temp1,temp2,symbolChar);
-
- numStack.push(result);
-
- }
-
- int res=numStack.pop();
-
- System.out.println("结果是:"+res);
-
- }
-
-
- }
测试结果



-
相关阅读:
SpringBoot介绍及自动装配
IMX6ULL学习笔记(7)——通过SD卡启动U-Boot
Spring基础:接口实现AOP
【批处理DOS-CMD命令-汇总和小结】-将文件夹映射成虚拟磁盘——subst
@FeignClient configuration参数配置
TS泛型的使用
《第一行代码》读书笔记(2)—日志工具Log
MFC3d立体按钮制作
华为hcip考试,询问您解答
MATLAB环境下基于稀疏最大谐波噪声比反卷积的信号处理方法
-
原文地址:https://blog.csdn.net/weixin_59334478/article/details/127459264