• 数据结构之栈的实现及相关OJ题


    🕺作者@启明星使

    🎃专栏:《数据库》《C语言》

    🏇分享一句话:

    对的人会站在你的前途里 志同道合的人才看得懂同一片风景

    大家一起加油🏄‍♂️🏄‍♂️🏄‍♂️

    希望得到大家的支持,如果有帮助希望得到的大家三连~~~afbae359ff6c469aa4242bd6dcb5e558.jpeg

    目录

    前言

    思路

    1. 定义结构体

    2.初始化

    3. 销毁

    4. 入栈

    2 容量足够:

    利用数组的性质将值赋给栈顶

    栈顶自增

    5. 出栈

    6. 栈长

    7. 栈空

    代码实现

    1. 定义结构体

    2. 初始化

    3. 销毁

    4. 入栈

    5. 出栈

    6. 栈长

    7. 栈空

    OJ题(简单)

    题解


    前言

    实现栈有很多种方式,在这里我们使用的方法是动态数组实现。

    栈的概念及结构 

    • 一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。
    • 进行数据插入和删除 操作的一端称为栈顶,另一端称为栈底。
    • 栈中的数据元素遵守后进先出LIFO(Last In First Out) 的原则。

    思路

    • 拓展:assert()内的条件若返回错误则停止程序 非必要只是方便Debug
    • tips:主函数中得先定义一个结构体变量

    1. 定义结构体

    • 数组
    • 栈顶
    • 记录存储容量的变量

    2.初始化

    • assert()断言:判断结构体是否存在
    • 先给数组开辟一个初始空间4
    • 判断开辟空间是否成功
    • 存储容量为4
    • 栈顶为0

    3. 销毁

    • assert()断言:判断结构体是否存在
    • 销毁数组,将数组置为NULL
    • 将栈顶的值和存储容量的变量置为0

    4. 入栈

    • assert()断言:判断结构体是否存在
      • 先判断容量是否足够:
      • 不够则增容(假设增两倍)
        这里用的是realloc
        会先将原数组的值先拷贝,开辟一个新空间增容
        • 增容后判断是否成功增容
        •  失败则打印增容失败
        •  成功则把新空间的地址赋给结构体变量里的数组
        •  存储容量的变量*2
      • 容量足够入栈:
        • 利用数组的性质将值赋给栈顶
        •  栈顶自增

    5. 出栈

    • 取栈顶值
      • assert()断言:判断结构体是否存在
      • assert()断言:判断栈顶是否大于0
      • 利用数组性质返回栈顶元素的值
    • 删去栈顶
      • assert()断言:判断结构体是否存在 a
      • ssert()断言:判断栈顶是否大于0
      • 栈顶位置减一

    6. 栈长

    • assert()断言:判断结构体是否存在
    • 返回栈顶下标即为栈长

    7. 栈空

    • assert()断言:判断结构体是否存在
    • 返回一个bool值 根据栈顶下标是否为0判断栈是否为空

    代码实现

    1. 定义结构体

    1. typedef struct Sqstack
    2. {
    3. Elemtype* a;
    4. int top;
    5. int capacity;
    6. }Sq;

    2. 初始化

    1. void Initstack(Sq*st) {
    2. assert(st);
    3. st->a = (Elemtype*)malloc(sizeof(Elemtype) * 4);
    4. if (st->a == NULL) {
    5. printf("malloc fail\n");
    6. exit(-1);
    7. }
    8. st->capacity = 4;
    9. st->top = 0;
    10. }

    3. 销毁

    1. void DestroySt(Sq* st) {
    2. assert(st);
    3. free(st->a);
    4. st->a = NULL;
    5. st->top = st->capacity = 0;
    6. }

    4. 入栈

    1. void InsertSt(Sq* st,Elemtype x) {
    2. assert(st);
    3. if (st->top == st->capacity) {
    4. Elemtype* tem = (Elemtype*)realloc(st->a, st->capacity * 2 * sizeof(Elemtype));
    5. if (tem == NULL) {
    6. printf("realloc fail\n");
    7. exit(-1);
    8. }
    9. else
    10. {
    11. st->a = tem;
    12. st->capacity *= 2;
    13. }
    14. }
    15. st->a[st->top] = x;
    16. st->top++;
    17. }

    5. 出栈

    1. Elemtype TopSt(Sq* st) {
    2. assert(st);
    3. assert(st->top > 0);
    4. return st->a[st->top -1];
    5. }
    6. void PopSt(Sq* st) {
    7. assert(st);
    8. assert(st->top > 0);
    9. st->top--;
    10. }

    6. 栈长

    1. int Stsize(Sq* st) {
    2. assert(st);
    3. return st->top;
    4. }

    7. 栈空

    1. bool StEmpty(Sq* st) {
    2. assert(st);
    3. return st->top == 0;
    4. }

    OJ题(简单)

    有效的括号

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

    有效字符串需满足:

    1. 左括号必须用相同类型的右括号闭合。

    2. 左括号必须以正确的顺序闭合。

    3. 每个右括号都有一个对应的相同类型的左括号。

    示例 1:

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

    示例 2:

    输入:s = "()[]{}"
    输出:true

    示例 3:

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

    提示:

    • 1 <= s.length <= 104

    • s 仅由括号 '()[]{}' 组成

    题解

    • 在这里我们使用了栈的思想,首先定义一个栈,然后拿栈顶和字符串的值配对
    • 所以我们使用了循环遍历,直到字符串结束为止打破循环,在循环里面,使用Swich语句
    • 如果是左括号则入栈,字符串遍历下一个
    • 如果是右括号,则先判断是否为空
    • 如果为空,则无需继续不可能配对成功了,打破循环结束,返回false
    • 如果不是空,则拿栈顶的元素和字符串中的元素配对,这里要记得出栈
    • 判断是否不匹配,如果不匹配则销毁栈,返回false,否则匹配继续遍历字符串,直到结束为止
    • 最后判断栈内是否为空,若为空则说明全部匹配成功返回true,否则返回false。
    1. typedef char Elemtype;
    2. typedef struct Sqstack
    3. {
    4. Elemtype* a;
    5. int top;
    6. int capacity;
    7. }Sq;
    8. void Initstack(Sq*st) {
    9. assert(st);
    10. st->a = (Elemtype*)malloc(sizeof(Elemtype) * 4);
    11. if (st->a == NULL) {
    12. printf("malloc fail\n");
    13. exit(-1);
    14. }
    15. st->capacity = 4;
    16. st->top = 0;
    17. }
    18. void DestroySt(Sq* st) {
    19. assert(st);
    20. free(st->a);
    21. st->a = NULL;
    22. st->top = st->capacity = 0;
    23. }
    24. void InsertSt(Sq* st,Elemtype x) {
    25. assert(st);
    26. if (st->top == st->capacity) {
    27. Elemtype* tem = (Elemtype*)realloc(st->a, st->capacity * 2 * sizeof(Elemtype));
    28. if (tem == NULL) {
    29. printf("realloc fail\n");
    30. exit(-1);
    31. }
    32. else
    33. {
    34. st->a = tem;
    35. st->capacity *= 2;
    36. }
    37. }
    38. st->a[st->top] = x;
    39. st->top++;
    40. }
    41. Elemtype TopSt(Sq* st) {
    42. assert(st);
    43. assert(st->top > 0);
    44. return st->a[st->top -1];
    45. }
    46. void PopSt(Sq* st) {
    47. assert(st);
    48. assert(st->top > 0);
    49. st->top--;
    50. }
    51. int Stsize(Sq* st) {
    52. assert(st);
    53. return st->top;
    54. }
    55. bool StEmpty(Sq* st) {
    56. assert(st);
    57. return st->top == 0;
    58. }
    59. int lengths(char*s){
    60.   int i=0;
    61.   while(s[i]!='\0'){
    62.       i++;
    63.   }
    64.   return i;
    65. }
    66. bool isValid(char * s){
    67.   Sq st;
    68.   Initstack(&st);
    69.    
    70.   while(*s !='\0'){
    71.       switch(*s)
    72.       {
    73.           case '{':
    74.           case '[':
    75.           case '(':
    76.           {
    77.               InsertSt(&st,*s);
    78.               ++s;
    79.               break;
    80.           }
    81.           case '}':
    82.           case ')':
    83.           case ']':
    84.           {
    85.               if(StEmpty(&st)){
    86.                   DestroySt(&st);
    87.                   return false;
    88.               }
    89.               char top=TopSt(&st);
    90.               PopSt(&st);
    91.               if((*s=='}'&&top!='{')
    92.               ||(*s==']'&&top!='[')
    93.               ||(*s==')'&&top!='('))
    94.               {
    95.                   DestroySt(&st);
    96.                   return false;
    97.               }
    98.               else{
    99.                   ++s;
    100.               }
    101.               break;
    102.           }
    103.           default:
    104.               break;
    105.       }
    106.   }
    107.   bool ret=StEmpty(&st);
    108.   DestroySt(&st);
    109.   return ret;
    110.        
    111. }

  • 相关阅读:
    Junit的常用操作
    浅谈云原生
    纳百川冲刺创业板上市:计划募资约8亿元,宁德时代为主要合作方
    IShellFolder2::GetDetailsOf第二个参数(UINT iColumn)数值对应详细信息的项
    阿里云服务器配置选择方案_CPU内存_带宽_系统盘
    动态规划:12最后一块石头的重量II
    信息化和数字化的核心差异
    【Serilog】具有完全结构化事件的简单.NET日志记录
    Day27:异常详解
    MyBatis 学习(一)之 MyBatis 概述
  • 原文地址:https://blog.csdn.net/m0_67759533/article/details/127937032