当前位置:   article > 正文

栈的详解和例题(力扣有效括号)_栈 例题

栈 例题

感谢各位大佬的光临,希望和大家一起进步,望得到你的三连,互三支持,一起进步

个人主页LaNzikinh-CSDN博客

收入专栏:初阶数据结构_LaNzikinh篮子的博客-CSDN博客

文章目录

  • 前言
  • 一.什么是栈
  • 二.栈的实现
  • 三.例题(力扣)
  • 总代码

前言

之前讲了,很多关于栈的习题,还有栈与队列的互相转换,还是补一篇栈的详解


一.什么是栈

栈(stack)是一种只允许在一端进行插入和删除操作的线性表。这一端称为栈顶,另一端称为栈底。栈的特点是后进先出(LIFO),即最后进入的元素最先出来。栈可以用来存储局部变量和一些数据,当函数或线程执行完毕,栈就会释放空间。

二.栈的实现

这样的实现它分为两种,一种是用数组去实现栈,另一种就是用链表去实现栈,我们这里主要讲的是用数组去实现栈,用链表实现栈又叫做链式栈,如果用尾做为栈顶那么尾插尾删就要设计成双向链表,否则删除数据效率会很低。

2.1结构

注意:初始化时把top=0的话,top可以看成有栈中的元素总数,不是栈顶的元素下标!!

  1. typedef int STDataType;
  2. typedef struct stack
  3. {
  4. STDataType* a;
  5. int top;
  6. int capacity
  7. }ST;

其实就可以把它看成一个顺序表,top就是size的意思,它用来控制栈顶的元素的

2.2初始化

初始化时,top给的是0的话,意味着top栈顶数据的指向下一个,top给-1的话,意味着top就是栈顶数据

  1. void stackInit(ST* ps)
  2. {
  3. assert(ps);
  4. ps->a = NULL;
  5. ps->top = 0;//ps->top=-1;
  6. ps->capacity = 0;
  7. }

2.3放入数据

这里和顺序表的扩容和插入一模一样

  1. void stackPush(ST* ps, STDataType x)
  2. {
  3. assert(ps);
  4. //检查扩容
  5. if (ps->top == ps->capacity)
  6. {
  7. int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
  8. STDataType* tmp = (STDataType*)realloc(ps->a,sizeof(STDataType) * newcapacity);
  9. assert(tmp);
  10. ps->a = tmp;
  11. ps->capacity = newcapacity;
  12. }
  13. ps->a[ps->top] = x;
  14. ps->top++;
  15. }

 2.4删数据和取栈顶元素

我初始化的top为0,所以取栈顶元素的下标是top-1

  1. void stackPop(ST* ps)
  2. {
  3. assert(ps);
  4. assert(ps->top > 0);
  5. ps->top--;
  6. }
  7. STDataType stackTop(ST* ps)
  8. {
  9. assert(ps);
  10. assert(ps->top > 0);
  11. //我初始化的top为0,所以取栈顶元素的下标是top-1
  12. return ps->a[ps->top -1 ];
  13. }

2.5检查栈中还要元素和释放

  1. bool stackEmpty(ST* ps)
  2. {
  3. assert(ps);
  4. //说明栈里没有元素了
  5. if (ps->top == 0)
  6. return true;
  7. else
  8. return false;
  9. }
  10. void stackDestroy(ST* ps)
  11. {
  12. assert(ps);
  13. free(ps->a);
  14. ps->a = NULL;
  15. ps->capacity = ps->top = 0;
  16. }

然后我们来看一道例题

三.例题(力扣)

给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

示例 1:

输入:s = "()"
输出:true
输入:s = "(]"
输出:false

20. 有效的括号 - 力扣(LeetCode)

思路:利用栈算法先搭建一个栈,然后我们先让左括号入栈,在让左括号出栈和右括号匹配

注意:因为如果用C语言去写,c语言中的库没有栈的,所以必须自己搭建一个栈,就是我们上面写的

3.1

我们先断言一下传来的不能是空指针,然后对栈进行初始化,然后设置一个循环,意思是说等这个字符串走完了之后这个循环就出了,第一步判断我们先得让左括号入栈,如果是左括号的就入栈,然后字符串加加

  1. assert(s);
  2. ST st;
  3. stackInit(&st);
  4. while (*s)
  5. {
  6. if (*s == '(' || *s == '{' || *s == '[')
  7. {
  8. stackPush(&st, *s);
  9. s++;
  10. }

3.2

然后如果不是左括号我们就可以进行第一次判断了,如果遇到了右括号,但是栈里没有数据,说明前面没有右括号不匹配,我们直接退出,如果不是这个错误的话,我们就可以取栈顶元素,把这个括号取出来删掉,然后进行左括号匹配,如果不是就直接退出,注意:stackDestroy(&st);为什么我要提前放不在后面放,因为我在这里就退出了存在开屏内存没有释放会造成内存泄露。

  1. else
  2. {
  3. if (stackEmpty(&st))
  4. {
  5. return false;
  6. }
  7. STDataType top = stackTop(&st);
  8. stackPop(&st);
  9. if ((*s == ')' && top != '(') || (*s == '}' && top != '{') || (*s == ']' && top != '['))
  10. {
  11. stackDestroy(&st);
  12. return false;
  13. }
  14. else {
  15. s++;
  16. }
  17. }

3.3

如果只有左括号没有右括号呢,所以我的结尾判断还需要特殊一点,如果栈里还有元素的话就说明还存在左括号没有出去没有匹配,所以我也不能返回正确

  1. bool ret = stackEmpty(&st);
  2. stackDestroy(&st);
  3. return ret;

总代码

注意这个题目是符号判断,所以我的STDataType是char类型的

  1. typedef char STDataType;
  2. typedef struct stack
  3. {
  4. STDataType* a;
  5. int top;
  6. int capacity;
  7. }ST;
  8. void stackInit(ST* ps)
  9. {
  10. assert(ps);
  11. ps->a = NULL;
  12. ps->top = 0;
  13. ps->capacity = 0;
  14. }
  15. void stackPush(ST* ps, STDataType x)
  16. {
  17. assert(ps);
  18. //检查扩容
  19. if (ps->top == ps->capacity)
  20. {
  21. int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
  22. STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newcapacity);
  23. assert(tmp);
  24. ps->a = tmp;
  25. ps->capacity = newcapacity;
  26. }
  27. ps->a[ps->top] = x;
  28. ps->top++;
  29. }
  30. void stackDestroy(ST* ps)
  31. {
  32. assert(ps);
  33. free(ps->a);
  34. ps->a = NULL;
  35. ps->capacity = ps->top = 0;
  36. }
  37. void stackPop(ST* ps)
  38. {
  39. assert(ps);
  40. assert(ps->top > 0);
  41. ps->top--;
  42. }
  43. STDataType stackTop(ST* ps)
  44. {
  45. assert(ps);
  46. assert(ps->top > 0);
  47. return ps->a[ps->top - 1];
  48. }
  49. bool stackEmpty(ST* ps)
  50. {
  51. assert(ps);
  52. if (ps->top == 0)
  53. return true;
  54. else
  55. return false;
  56. }
  57. bool isValid(char* s)
  58. {
  59. assert(s);
  60. ST st;
  61. stackInit(&st);
  62. while (*s)
  63. {
  64. if (*s == '(' || *s == '{' || *s == '[')
  65. {
  66. stackPush(&st, *s);
  67. s++;
  68. }
  69. else
  70. {
  71. if (stackEmpty(&st))
  72. {
  73. return false;
  74. }
  75. STDataType top = stackTop(&st);
  76. stackPop(&st);
  77. if ((*s == ')' && top != '(') || (*s == '}' && top != '{') || (*s == ']' && top != '['))
  78. {
  79. stackDestroy(&st);
  80. return false;
  81. }
  82. else {
  83. s++;
  84. }
  85. }
  86. }
  87. bool ret = stackEmpty(&st);
  88. stackDestroy(&st);
  89. return ret;
  90. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/781241
推荐阅读
相关标签
  

闽ICP备14008679号