当前位置:   article > 正文

数据结构:栈(含源码)

数据结构:栈(含源码)

目录

一、栈的概念和结构

 二、栈的实现

2.1 头文件

2.2 各个功能的实现

初始化栈

入栈

出栈

获取栈顶元素和栈中有效个数

 判断栈是否为空

栈的销毁

2.3 测试

完整源码


一、栈的概念和结构

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

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶

出栈:栈的删除操作叫做出栈,出数据也在栈顶

后进先出示意图

 后进先出步骤分解

 二、栈的实现

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

2.1 头文件

  1. #include<stdio.h>
  2. #include<assert.h>
  3. #include<stdlib.h>
  4. #include<stdbool.h>
  5. typedef int STDataType;
  6. typedef struct Stack
  7. {
  8. STDataType* a;
  9. int top; // 栈顶
  10. int capacity; // 容量
  11. }Stack;
  12. // 初始化栈
  13. void StackInit(Stack* ps);
  14. // 入栈
  15. void StackPush(Stack* ps, STDataType data);
  16. // 出栈
  17. void StackPop(Stack* ps);
  18. // 获取栈顶元素
  19. STDataType StackTop(Stack* ps);
  20. // 获取栈中有效元素个数
  21. int StackSize(Stack* ps);
  22. // 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
  23. bool StackEmpty(Stack* ps);
  24. // 销毁栈
  25. void StackDestroy(Stack* ps);

我们在创建栈时,一般是创建支持动态增长的栈,定长的静态栈不实用。这里的top就相当于是存储栈顶元素,capacity在入栈时为是否要增容提供判断条件。

2.2 各个功能的实现

初始化

  1. void StackInit(Stack* ps)
  2. {
  3. ps->a = NULL;
  4. ps->top = ps->capacity = 0;
  5. }

    数组置空,栈顶数字和容量归0。

入栈

  1. void StackPush(Stack* ps, STDataType data)
  2. {
  3. if (ps->top == ps->capacity)
  4. {
  5. int newcapacity =ps->capacity== 0 ? 4 : ps->capacity*2;
  6. STDataType* tem = (STDataType*)realloc(ps->a, newcapacity*sizeof(STDataType));
  7. if (tem == NULL)
  8. {
  9. perror("realloc fail");
  10. return;
  11. }
  12. ps->capacity = newcapacity;
  13. ps->a = tem;
  14. }
  15. ps->a[ps->top++] = data;
  16. }

    先判断容量是否有足够的空间让数据入栈,在第一次入栈是先给定4个空间,后面每次不够时就将空间数乘以2, 还有一个判断是否开辟成功(这个可以不写,一般都会开辟成功)。

出栈

  1. void StackPop(Stack* ps)
  2. {
  3. assert(ps);
  4. ps->top--;
  5. }

    出栈非常的简单,只要将top数减少一个就行了,相当于是下一次入栈是直接把这个数据修改掉,就算没修改,打印时也不影响。

获取栈顶元素和栈中有效个数

  1. STDataType StackTop(Stack* ps)
  2. {
  3. assert(ps);
  4. assert(ps->top > 0);
  5. return ps->a[ps->top-1];
  6. }
  1. int StackSize(Stack* ps)
  2. {
  3. assert(ps);
  4. return ps->top;
  5. }

    两个都是比较简单的代码,只要用top就可以知道栈顶元素和栈中的元素个数。 

 判断栈是否为空

  1. bool StackEmpty(Stack* ps)
  2. {
  3. assert(ps);
  4. return ps->top == 0;
  5. }

    栈中个数为0那么就是空栈,也是直接用到了top,。

栈的销毁

  1. void StackDestroy(Stack* ps)
  2. {
  3. assert(ps);
  4. free(ps->a);
  5. ps->a = NULL;
  6. ps->capacity = 0;
  7. ps->top = 0;
  8. }

    和初始化类似,数组置空,top和capacity归0。

2.3 测试

    写完代码后还是需要测试的

  1. int main()
  2. {
  3. Stack s;
  4. StackInit(&s);
  5. StackPush(&s, 1);
  6. StackPush(&s, 2);
  7. StackPush(&s, 3);
  8. StackPush(&s, 4);
  9. StackPush(&s, 5);
  10. while (!StackEmpty(&s))
  11. {
  12. printf("%d\n", StackTop(&s));
  13. StackPop(&s);
  14. }
  15. StackDestroy(&s);
  16. }

     我这里就是先入栈五个元素,然后在一个循环中打印,每打印一个就将栈顶元素出栈,直到栈变为空栈结束打印。

完整源码

zhan.h

  1. #include<stdio.h>
  2. #include<assert.h>
  3. #include<stdlib.h>
  4. #include<stdbool.h>
  5. typedef int STDataType;
  6. typedef struct Stack
  7. {
  8. STDataType* a;
  9. int top;
  10. int capacity;
  11. }Stack;
  12. void StackInit(Stack* ps);
  13. void StackPush(Stack* ps, STDataType data);
  14. void StackPop(Stack* ps);
  15. STDataType StackTop(Stack* ps);
  16. int StackSize(Stack* ps);
  17. bool StackEmpty(Stack* ps);
  18. void StackDestroy(Stack* ps);

 zhan.c

  1. #include"zhan.h"
  2. void StackInit(Stack* ps)
  3. {
  4. ps->a = NULL;
  5. ps->top = ps->capacity = 0;
  6. }
  7. void StackPush(Stack* ps, STDataType data)
  8. {
  9. if (ps->top == ps->capacity)
  10. {
  11. int newcapacity =ps->capacity== 0 ? 4 : ps->capacity*2;
  12. STDataType* tem = (STDataType*)realloc(ps->a, newcapacity*sizeof(STDataType));
  13. if (tem == NULL)
  14. {
  15. perror("realloc fail");
  16. return;
  17. }
  18. ps->capacity = newcapacity;
  19. ps->a = tem;
  20. }
  21. ps->a[ps->top++] = data;
  22. }
  23. void StackPop(Stack* ps)
  24. {
  25. assert(ps);
  26. ps->top--;
  27. }
  28. STDataType StackTop(Stack* ps)
  29. {
  30. assert(ps);
  31. assert(ps->top > 0);
  32. return ps->a[ps->top-1];
  33. }
  34. int StackSize(Stack* ps)
  35. {
  36. assert(ps);
  37. return ps->top;
  38. }
  39. bool StackEmpty(Stack* ps)
  40. {
  41. assert(ps);
  42. return ps->top == 0;
  43. }
  44. void StackDestroy(Stack* ps)
  45. {
  46. assert(ps);
  47. free(ps->a);
  48. ps->a = NULL;
  49. ps->capacity = 0;
  50. ps->top = 0;
  51. }

     最好是要自己写一遍,这样才能加深印象,也更能理解栈相关的知识。


    本篇关于栈的内容就到这里了,希望对各位有帮助,如果有错误欢迎指出,感谢支持。

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

闽ICP备14008679号