当前位置:   article > 正文

数据结构——栈

数据结构——栈

大家好我是小锋,今天我们来学习一下栈,

栈的概念及结构 

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。
栈中的数据元素遵守  后进先出  LIFO Last In First Out )的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。
那么大家思考一个问题我们在压栈1,2,3,4,它出栈就是4,3,2,1,吗?
其实不一定我们可以边压栈边出栈它的顺序也可以是1,2,3,4,

栈的实现

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
这里我们用顺序表来实现栈
这里有两种版本的顺序表静态的实际应用不大,我们用动态的版本来实现链表。
我们再分装一个.h文件来存放头文件

初始化

  1. //初始化
  2. void stackinit(stack* ps) {
  3. assert(ps);
  4. ps->val = NULL;
  5. ps->capacity = 0;
  6. ps->top = 0;
  7. }

压栈

  1. //压栈
  2. void stackpush(stack* ps,CMMlet a) {
  3. assert(ps);
  4. if (ps->capacity == ps->top) {
  5. int n = ps->val == NULL ? 4 : ps->capacity * 2;
  6. CMMlet* cur = (CMMlet*)realloc(ps->val, n * sizeof(CMMlet));
  7. if (cur == NULL) {
  8. printf("%s", strerror(errno));
  9. return;
  10. }
  11. ps->val = cur;
  12. ps->capacity = n;
  13. }
  14. ps->val[ps->top] = a;
  15. ps->top++;
  16. }

这里的操作都是顺序表的常规操作了我就不细说了

出栈

  1. //出栈
  2. void stackpop(stack* ps) {
  3. assert(ps);
  4. assert(stackEmpty(ps));
  5. ps->top--;
  6. }

这里我们主要注意(栈为空时不能继续出栈了)

这里我们可以写一个函数来判断,

  1. //检测栈是否为空(空返回0,非空返回非0)
  2. int stackEmpty(stack* ps) {
  3. assert(ps);
  4. return ps->top;
  5. }

获取栈顶元素

  1. //获取栈顶元素
  2. CMMlet stacktop(stack* ps) {
  3. assert(ps);
  4. assert(stackEmpty(ps));
  5. return ps->val[ps->top - 1];
  6. }

获取栈中有效元素个数

  1. //获取栈中有效元素个数
  2. int stacksize(stack* ps) {
  3. assert(ps);
  4. assert(stackEmpty(ps));
  5. return ps->top;
  6. }

销毁栈

  1. //销毁栈
  2. void stackdestroy(stack* ps) {
  3. assert(ps);
  4. assert(!stackEmpty(ps));
  5. free(ps->val);
  6. ps->val = NULL;
  7. }

我们写个函数来验证一下我们写的栈是否可以正常操作

先写个函数输出表中的数据(这违背了栈的概念所有不在栈的操作中只是为了方便测试

  1. // 打印栈
  2. void stackdy(stack* ps) {
  3. for (int i = 0; i < ps->top; i++) {
  4. printf("%d", ps->val[i]);
  5. }
  6. printf("\n");
  7. }
  8. //测试函数
  9. void stackcs() {
  10. stack ps;
  11. //初始化
  12. stackinit(&ps);
  13. //压栈
  14. stackpush(&ps, 1);
  15. stackpush(&ps, 2);
  16. stackpush(&ps, 3);
  17. stackpush(&ps, 4);
  18. stackpush(&ps, 5);
  19. stackdy(&ps);
  20. //出栈
  21. stackpop(&ps);
  22. stackpop(&ps);
  23. stackdy(&ps);
  24. //获取栈顶
  25. CMMlet n=stacktop(&ps);
  26. printf("%d\n", n);
  27. //获取元素个数
  28. stacksize(&ps);
  29. //销毁栈
  30. stackdestroy(&ps);
  31. }
  32. int main() {
  33. stackcs();
  34. return 0;
  35. }

下面就是本期的所有代码,大家可以自己尝试一下

test.h

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #pragma once
  3. # include<stdio.h>
  4. # include<stdlib.h>
  5. # include<assert.h>
  6. # include<string.h>
  7. # include<errno.h>
  8. #define N 10
  9. typedef int CMMlet;
  10. typedef struct stack stack;
  11. 静态版本
  12. //struct stack {
  13. // int top;//栈顶
  14. // CMMlet val[N]
  15. //};
  16. //动态版本
  17. struct stack {
  18. int top;//栈顶
  19. CMMlet* val;
  20. int capacity;//容量
  21. };
  22. //初始化
  23. void stackinit(stack* ps);
  24. //压栈
  25. void stackpush(stack* ps, CMMlet a);
  26. //出栈
  27. void stackpop(stack* ps);
  28. //获取栈顶元素
  29. CMMlet stacktop(stack* ps);
  30. //获取栈中有效元素个数
  31. int stacksize(stack* ps);
  32. //检测栈是否为空(空返回0,非空返回非0)
  33. int stackEmpty(stack* ps);
  34. //销毁栈
  35. void stackdestroy(stack* ps);

test.c

  1. # include"test.h"
  2. //初始化
  3. void stackinit(stack* ps) {
  4. assert(ps);
  5. ps->val = NULL;
  6. ps->capacity = 0;
  7. ps->top = 0;
  8. }
  9. //压栈
  10. void stackpush(stack* ps,CMMlet a) {
  11. assert(ps);
  12. if (ps->capacity == ps->top) {
  13. int n = ps->val == NULL ? 4 : ps->capacity * 2;
  14. CMMlet* cur = (CMMlet*)realloc(ps->val, n * sizeof(CMMlet));
  15. if (cur == NULL) {
  16. printf("%s", strerror(errno));
  17. return;
  18. }
  19. ps->val = cur;
  20. ps->capacity = n;
  21. }
  22. ps->val[ps->top] = a;
  23. ps->top++;
  24. }
  25. //出栈
  26. void stackpop(stack* ps) {
  27. assert(ps);
  28. assert(stackEmpty(ps));
  29. ps->top--;
  30. }
  31. //获取栈顶元素
  32. CMMlet stacktop(stack* ps) {
  33. assert(ps);
  34. assert(stackEmpty(ps));
  35. return ps->val[ps->top - 1];
  36. }
  37. //获取栈中有效元素个数
  38. int stacksize(stack* ps) {
  39. assert(ps);
  40. assert(stackEmpty(ps));
  41. return ps->top;
  42. }
  43. //检测栈是否为空(空返回0,非空返回非0)
  44. int stackEmpty(stack* ps) {
  45. assert(ps);
  46. return ps->top;
  47. }
  48. //销毁栈
  49. void stackdestroy(stack* ps) {
  50. assert(ps);
  51. free(ps->val);
  52. ps->val = NULL;
  53. ps->top = ps->capacity = 0;
  54. }

cs.c

  1. #include"test.h"
  2. // 打印栈
  3. void stackdy(stack* ps) {
  4. for (int i = 0; i < ps->top; i++) {
  5. printf("%d", ps->val[i]);
  6. }
  7. printf("\n");
  8. }
  9. //测试函数
  10. void stackcs() {
  11. stack ps;
  12. //初始化
  13. stackinit(&ps);
  14. //压栈
  15. stackpush(&ps, 1);
  16. stackpush(&ps, 2);
  17. stackpush(&ps, 3);
  18. stackpush(&ps, 4);
  19. stackpush(&ps, 5);
  20. stackdy(&ps);
  21. //出栈
  22. stackpop(&ps);
  23. stackpop(&ps);
  24. stackdy(&ps);
  25. //获取栈顶
  26. CMMlet n = stacktop(&ps);
  27. printf("%d\n", n);
  28. //获取元素个数
  29. int a = stacksize(&ps);
  30. printf("%d\n", a);
  31. stackdy(&ps);
  32. //销毁栈
  33. stackdestroy(&ps);
  34. }
  35. int main() {
  36. stackcs();
  37. return 0;
  38. }

   以上就是全部内容了,如果有错误或者不足的地方欢迎大家给予建议。 

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

闽ICP备14008679号