• 数据结构与算法:栈(java)


    1.栈的介绍

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

    弹栈:

    栈实现

    由于栈是一个表,因此任何实现表的方法都可以用来实现栈。主要有两种方式,链表实现和数组实现。

    链表实现栈

    可以使用单链表来实现栈。通过在表顶端插入一个元素来实现 PUSH,通过删除表顶端元素来实现 POP。使用链表方式实现的栈又叫动态栈。动态栈有链表的部分特性,即元素与元素之间在物理存储上可以不连续,但是功能有些受限制,动态栈只能在栈顶处进行插入和删除操作,不能在栈尾或栈中间进行插入和删除操作。

    数组实现栈

    栈也可以用数组来实现。使用数组方式实现的栈叫静态栈

    2.栈的应用场景

    3.栈的快速入门

    习题1:使用数组来模拟栈的使用

    ArrayStack类

    1. package stack;
    2. public class ArrayStack {
    3. //栈的大小
    4. private int maxStack;
    5. //数组用来模拟栈
    6. private int[] stack;
    7. //表示栈顶的所在的位置,默认情况下没有数据使用-1
    8. private int top=-1;
    9. //有参构造
    10. public ArrayStack(int maxStack){
    11. this.maxStack=maxStack;
    12. stack=new int[maxStack];
    13. }
    14. //判断栈是否是空栈
    15. public boolean isFull(){
    16. return this.top==maxStack-1;
    17. }
    18. //判断栈是否是空栈
    19. public boolean isEmpty(){
    20. return this.top==-1;
    21. }
    22. //压栈
    23. public void push(int val){
    24. //是否已经栈满
    25. if(isFull()){
    26. throw new RuntimeException("此栈已满");
    27. }
    28. top++;
    29. stack[top]=val;
    30. }
    31. //弹栈
    32. public int pop(){
    33. if (isEmpty()){
    34. throw new RuntimeException("空栈,未找到数据!");
    35. }
    36. int value=stack[top];
    37. top--;
    38. return value;
    39. }
    40. //查看栈中所有的元素
    41. public void list(){
    42. //是否是空栈
    43. if (isEmpty()){
    44. throw new RuntimeException("空栈,未找到数据!");
    45. }
    46. for (int i=0;i
    47. System.out.printf("stack[%d]=%d\n", i ,stack[i]);
    48. }
    49. }
    50. //栈中元素存在的个数
    51. public int length(){
    52. return this.top+1;
    53. }
    54. }

    习题2:回文数

    回文: 一个单词、短语或数字,从前往后写和从后往前写都是一样的。比如,单词“dad”、“racecar”就是回文;如果忽略空格和             标点符号,下面这个句子也是回文,“A man, a plan, a canal: Panama”, 数字1001 也是回文。

    思路:使用栈,可以轻松判断一个字符串是否是回文。我们将拿到的字符串的每个字符按从左至右的顺序压入栈。当字符串中的字符都入栈后,栈内就保存了一个反转后的字符串,最后的字符在栈顶,第一个字符在栈底。

    Test类

    1. package stack;
    2. import java.util.Arrays;
    3. public class Test {
    4. public static void main(String[] args) {
    5. /**
    6. * 回文数据
    7. * 回文:aba racecar 回文就是压栈字符串顺序和出栈字符串顺序相等。
    8. * 需求:通过上面数组模拟栈,判断字符串是否是一个回文数据
    9. */
    10. System.out.println(detecation("aba"));
    11. }
    12. public static boolean detecation(String val){
    13. //初始化栈对象
    14. ArrayStack arrayStack=new ArrayStack(10);
    15. //获取字符串长度
    16. int length = val.length();
    17. //把字符串数据逐次获取字符压栈到数组中
    18. for (int i=0;i
    19. arrayStack.push(val.charAt(i));
    20. }
    21. //把字符串的数据逐次弹出
    22. String newVal="";
    23. int length1=arrayStack.length();
    24. for (int i=0;i
    25. //是否是一个空栈
    26. if (!arrayStack.isEmpty()){
    27. char pop= (char) arrayStack.pop();
    28. newVal+=pop;
    29. }
    30. }
    31. if (val.equals(newVal)){
    32. return true;
    33. }
    34. return false;
    35. }
    36. }

    测试结果

     

     

     4.栈实现计算器

    首先在ArrayStack类中编写测试类所需要的方法

    ArrayStack类

    1. package stack;
    2. public class ArrayStack {
    3. //栈的大小
    4. private int maxStack;
    5. //数组用来模拟栈
    6. private int[] stack;
    7. //表示栈顶的所在的位置,默认情况下没有数据使用-1
    8. private int top=-1;
    9. //有参构造
    10. public ArrayStack(int maxStack){
    11. this.maxStack=maxStack;
    12. stack=new int[maxStack];
    13. }
    14. //判断栈是否是空栈
    15. public boolean isFull(){
    16. return this.top==maxStack-1;
    17. }
    18. //判断栈是否是空栈
    19. public boolean isEmpty(){
    20. return this.top==-1;
    21. }
    22. //压栈
    23. public void push(int val){
    24. //是否已经栈满
    25. if(isFull()){
    26. throw new RuntimeException("此栈已满");
    27. }
    28. top++;
    29. stack[top]=val;
    30. }
    31. //弹栈
    32. public int pop(){
    33. if (isEmpty()){
    34. throw new RuntimeException("空栈,未找到数据!");
    35. }
    36. int value=stack[top];
    37. top--;
    38. return value;
    39. }
    40. //查看栈中所有的元素
    41. public void list(){
    42. //是否是空栈
    43. if (isEmpty()){
    44. throw new RuntimeException("空栈,未找到数据!");
    45. }
    46. for (int i=0;i
    47. System.out.printf("stack[%d]=%d\n", i ,stack[i]);
    48. }
    49. }
    50. //栈中元素存在的个数
    51. public int length(){
    52. return this.top+1;
    53. }
    54. //判断是否是一个运算符+ - * |
    55. public boolean isOper(char v){
    56. return v=='+' || v=='-' || v=='*' || v=='/';
    57. }
    58. //判断优先符的优先级,用数字表示优先级的大小,数字越大优先级越大
    59. public int priority(int oper){
    60. if (oper=='*' || oper=='/'){
    61. return 1;
    62. }else if (oper=='+' || oper=='-'){
    63. return 0;
    64. }else {
    65. return -1;
    66. }
    67. }
    68. //获取栈的栈顶数据
    69. public int peek(){
    70. return this.stack[top];
    71. }
    72. //获取栈的容量
    73. public int stackLength(){
    74. return this.stack.length;
    75. }
    76. //计算两个数进行运算后的结果(出栈时是先进后出)
    77. public int calculate(int num1,int num2,int oper){
    78. //计算结果
    79. int result=0;
    80. switch (oper){
    81. case '+':
    82. result = num1+num2;
    83. break;
    84. case '-':
    85. result= num2-num1;
    86. break;
    87. case '*':
    88. result=num1*num2;
    89. break;
    90. case '/':
    91. result=num2/num1;
    92. break;
    93. default:
    94. break;
    95. }
    96. return result;
    97. }
    98. }

    Test2测试类

    1. package stack;
    2. public class Test2 {
    3. public static void main(String[] args) {
    4. String str="4+3*2-1";
    5. ArrayStack numStack=new ArrayStack(10);
    6. ArrayStack symbolStack=new ArrayStack(10);
    7. int temp1=0;
    8. int temp2=0;
    9. int symbolChar=0;
    10. int result=0;
    11. //获取字符串的长度
    12. int length = str.length();
    13. String values="";
    14. for (int i=0;i
    15. char c = str.charAt(i);
    16. //判断是否是一个运算符
    17. if (symbolStack.isOper(c)){
    18. //如果不是一个空的符号栈
    19. if (!symbolStack.isEmpty()){
    20. //比较运算符的优先级
    21. if (symbolStack.priority(c)
    22. /**
    23. * 1.去符号栈中获取栈顶的符号
    24. * 2.去数字栈中获取两个数字
    25. */
    26. temp1 = numStack.pop();
    27. temp2=numStack.pop();
    28. symbolChar = symbolStack.pop();
    29. result=numStack.calculate(temp1,temp2,symbolChar);
    30. //把运算结果再次放入数字栈中
    31. numStack.push(result);
    32. //把当前符号压入符号栈中
    33. symbolStack.push(c);
    34. }else {
    35. symbolStack.push(c);
    36. }
    37. }else {
    38. //如果是空字符栈,将运算符直接压栈
    39. symbolStack.push(c);
    40. }
    41. }else {
    42. values+=c;
    43. if (i==length-1){
    44. numStack.push(Integer.parseInt(values));
    45. }else {
    46. char c1 = str.substring(i + 1, i + 2).charAt(0);
    47. if (symbolStack.isOper(c1)){
    48. numStack.push(Integer.parseInt(values));
    49. values="";
    50. }
    51. }
    52. }
    53. }
    54. while (true){
    55. if (symbolStack.isEmpty()){
    56. break;
    57. }
    58. temp1=numStack.pop();
    59. temp2=numStack.pop();
    60. symbolChar=symbolStack.pop();
    61. result=numStack.calculate(temp1,temp2,symbolChar);
    62. numStack.push(result);
    63. }
    64. int res=numStack.pop();
    65. System.out.println("结果是:"+res);
    66. }
    67. }

    测试结果

     

     

     

  • 相关阅读:
    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