当前位置:   article > 正文

【数据结构初阶】栈

【数据结构初阶】栈

目录

一、栈的概念及结构

二、栈的实现

        2.1 定义一个栈结构

        2.2 初始化栈

        2.3 销毁栈 

        2.4 入栈

        2.5 出栈 

        2.6 获取栈顶元素数据

        2.7获取栈中有效元素个数 

        2.8检测栈是否为空

        2.9 测试

三、栈实现全部代码


一、栈的概念及结构

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

栈就像弹夹一样,后压入的子弹先打出去,先压入的子弹后打出去。

下面是栈进出元素的模拟过程:

二、栈的实现

        栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小,并且CPU缓冲利用率也更高。

        下面我们主要使用数组来实现栈。

        2.1 定义一个栈结构

在实现栈之前我们先要确定栈的结构:这里我们使用自定义结构体类型Stack来实现我们的栈,其中有可动态扩容的数据类型 _a,一个记录栈内所储存元素总个数(栈顶)的_top,和一个记录栈总可以存储数据元素个数的_capacity。

  1. typedef int STDataType;//数据类型
  2. typedef struct Stack
  3. {
  4. STDataType* _a; //数据
  5. int _top; // 栈顶
  6. int _capacity; // 容量
  7. }Stack;

:这里的对int类型进行重定义是为了我们更好的看懂STDataType只是一种数据而不仅仅是int类型。所以我们在使用栈时存储的数据并不限制于int类型,这里仅仅是举例。

        2.2 初始化栈

  1. void StackInit(Stack* ps)
  2. {
  3. assert(ps);//传入的指针不能为空
  4. ps->_a = (STDataType*)malloc(sizeof(STDataType)*4);//给栈开一个可以容纳4个数据单位的空间
  5. if (ps->_a == NULL)//判断开辟是否成功
  6. {
  7. perror("malloc");
  8. exit(-1);
  9. }
  10. ps->_capacity = 4;//初始栈容量为4
  11. ps->_top = 0;//初始栈内元素为0
  12. }

        2.3 销毁栈 

  1. void StackDestroy(Stack* ps)
  2. {
  3. assert(ps);//传入的指针不能为空
  4. free(ps->_a);//释放栈数据空间
  5. ps->_capacity = 0;//将栈容量改为0
  6. ps->_top = 0;//将栈顶该为0
  7. }

        2.4 入栈

  1. void StackPush(Stack* ps, STDataType data)
  2. {
  3. assert(ps);//传入的指针不能为空
  4. if (ps->_capacity == ps->_top)//判断栈是否已满,满了就扩容
  5. {
  6. STDataType* temp = (STDataType*)realloc(ps->_a, (ps->_capacity + 4) * sizeof(STDataType));
  7. if (temp == NULL)
  8. {
  9. perror("realloc");
  10. exit(-1);
  11. }
  12. ps->_a = temp;
  13. ps->_capacity += 4;
  14. }
  15. ps->_a[ps->_top] = data;//向栈内添加数据
  16. ps->_top++;//栈顶增加1
  17. }

        2.5 出栈 

  1. void StackPop(Stack* ps)
  2. {
  3. assert(ps);//传入的指针不能为空
  4. if (ps->_top <= 0)//栈空就不可出栈了
  5. return;
  6. ps->_top--;
  7. }

        2.6 获取栈顶元素数据

  1. STDataType StackTop(Stack* ps)
  2. {
  3. assert(ps);//传入的指针不能为空
  4. assert(ps->_top > 0);//栈不能为空
  5. return ps->_a[ps->_top - 1];//返回栈顶元素
  6. }

        2.7获取栈中有效元素个数 

  1. int StackSize(Stack* ps)
  2. {
  3. assert(ps);//传入的指针不能为空
  4. return ps->_top;//此时栈顶元素下标-1就为栈中有效元素个数
  5. }

        2.8检测栈是否为空

  1. bool StackEmpty(Stack* ps)
  2. {
  3. assert(ps);//传入的指针不能为空
  4. return ps->_top == 0;//判断栈是否为空
  5. }

        2.9 测试

  1. void Test()
  2. {
  3. Stack s;
  4. StackInit(&s);
  5. printf("栈是否为空:%d\n", StackEmpty(&s));
  6. StackPush(&s, 1);
  7. printf("栈内元素个数:%d,栈顶元素数据:%d,栈是否为空:%d\n", StackSize(&s), StackTop(&s), StackEmpty(&s));
  8. StackPush(&s, 2);
  9. printf("栈内元素个数:%d,栈顶元素数据:%d,栈是否为空:%d\n", StackSize(&s), StackTop(&s), StackEmpty(&s));
  10. StackPush(&s, 3);
  11. printf("栈内元素个数:%d,栈顶元素数据:%d,栈是否为空:%d\n", StackSize(&s), StackTop(&s), StackEmpty(&s));
  12. StackPush(&s, 4);
  13. printf("栈内元素个数:%d,栈顶元素数据:%d,栈是否为空:%d\n", StackSize(&s), StackTop(&s), StackEmpty(&s));
  14. StackPop(&s);
  15. printf("栈内元素个数:%d,栈顶元素数据:%d,栈是否为空:%d\n", StackSize(&s), StackTop(&s), StackEmpty(&s));
  16. StackPop(&s);
  17. printf("栈内元素个数:%d,栈顶元素数据:%d,栈是否为空:%d\n", StackSize(&s), StackTop(&s), StackEmpty(&s));
  18. StackPop(&s);
  19. printf("栈内元素个数:%d,栈顶元素数据:%d,栈是否为空:%d\n", StackSize(&s), StackTop(&s), StackEmpty(&s));
  20. StackDestroy(&s);
  21. printf("栈是否为空:%d\n", StackEmpty(&s));
  22. }

效果:

三、栈实现全部代码

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<assert.h>
  4. #include<stdbool.h>
  5. // 支持动态增长的栈
  6. typedef int STDataType;//数据类型
  7. typedef struct Stack
  8. {
  9. STDataType* _a; //数据
  10. int _top; // 栈顶
  11. int _capacity; // 容量
  12. }Stack;
  13. // 初始化栈
  14. void StackInit(Stack* ps)
  15. {
  16. assert(ps);//传入的指针不能为空
  17. ps->_a = (STDataType*)malloc(sizeof(STDataType)*4);//给栈开一个可以容纳4个数据单位的空间
  18. if (ps->_a == NULL)//判断开辟是否成功
  19. {
  20. perror("malloc");
  21. exit(-1);
  22. }
  23. ps->_capacity = 4;//初始栈容量为4
  24. ps->_top = 0;//初始栈内元素为0
  25. }
  26. // 入栈
  27. void StackPush(Stack* ps, STDataType data)
  28. {
  29. assert(ps);//传入的指针不能为空
  30. if (ps->_capacity == ps->_top)//判断栈是否已满,满了就扩容
  31. {
  32. STDataType* temp = (STDataType*)realloc(ps->_a, (ps->_capacity + 4) * sizeof(STDataType));
  33. if (temp == NULL)
  34. {
  35. perror("realloc");
  36. exit(-1);
  37. }
  38. ps->_a = temp;
  39. ps->_capacity += 4;
  40. }
  41. ps->_a[ps->_top] = data;//向栈内添加数据
  42. ps->_top++;//栈顶增加1
  43. }
  44. // 出栈
  45. void StackPop(Stack* ps)
  46. {
  47. assert(ps);//传入的指针不能为空
  48. if (ps->_top <= 0)//栈空就不可出栈了
  49. return;
  50. ps->_top--;
  51. }
  52. // 获取栈顶元素
  53. STDataType StackTop(Stack* ps)
  54. {
  55. assert(ps);//传入的指针不能为空
  56. assert(ps->_top > 0);//栈不能为空
  57. return ps->_a[ps->_top - 1];//返回栈顶元素
  58. }
  59. // 获取栈中有效元素个数
  60. int StackSize(Stack* ps)
  61. {
  62. assert(ps);//传入的指针不能为空
  63. return ps->_top;//此时栈顶元素下标-1就为栈中有效元素个数
  64. }
  65. // 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
  66. bool StackEmpty(Stack* ps)
  67. {
  68. assert(ps);//传入的指针不能为空
  69. return ps->_top == 0;//判断栈是否为空
  70. }
  71. // 销毁栈
  72. void StackDestroy(Stack* ps)
  73. {
  74. assert(ps);//传入的指针不能为空
  75. free(ps->_a);//释放栈数据空间
  76. ps->_capacity = 0;//初始栈容量为4
  77. ps->_top = 0;//初始栈内元素为0
  78. }


本期博客就到这啦,下面将会给大家大家带来数据结构的队列实现,敬请期待~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/641358
推荐阅读
相关标签
  

闽ICP备14008679号