史上最强数据结构----轻松拿捏栈的两种模拟实现

x33g5p2x  于2022-03-29 转载在 其他  
字(3.2k)|赞(0)|评价(0)|浏览(380)

1. 栈的概念及结构

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

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

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

注意:数据结构中的栈和我们C语言中的栈有什么关系吗?

前者是一种数据结构,用来存储数据。后者是操作系统中内存划分的一个区域,叫做栈,用来函数调用时,建立栈帧。

问:当入栈顺序是1 2 3 4的时候,出栈顺序一定是4 3 2 1吗?

答:不一定是,因为有可能是1入栈之后接着就出栈了,2、3、4也同样如此,此时的出栈顺序是1 2 3 4。实际上是有很多种出栈方式,后进先出是相对的。

2. 栈的实现

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

栈的代码实现:

2.1 数组栈的实现

第一种:数组栈的实现(推荐)

Stack.h文件代码:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<stdbool.h>
  4. #include<assert.h>
  5. typedef int STDataType;
  6. typedef struct Stack
  7. {
  8. STDataType* a;
  9. int top;//栈顶的位置
  10. int capacity;//容量
  11. }ST;
  12. void StackInit(ST*ps);
  13. void StackDestory(ST* ps);
  14. void StackPush(ST* ps,STDataType x);
  15. void StackPop(ST* ps);
  16. bool StackEmpty(ST* ps);
  17. int SizeStack(ST* ps);
  18. STDataType StackTop(ST* ps);

Stack.c文件代码:

  1. #include"Stack.h"
  2. void StackInit(ST* ps)//栈的初始化
  3. {
  4. assert(ps);
  5. ps->a = NULL;
  6. ps->capacity = 0;
  7. ps->top = 0;
  8. }
  9. void StackDestory(ST*ps)//栈的销毁
  10. {
  11. assert(ps);
  12. free(ps->a);
  13. ps->a = NULL;
  14. ps->capacity =ps->top = 0;
  15. }
  16. void StackPush(ST* ps, STDataType x)
  17. {
  18. assert(ps);
  19. if (ps->top == ps->capacity)//满了进行扩容
  20. {
  21. int newCapacity = ps->capacity == 0 ? 2 : 2 * ps->capacity;
  22. STDataType*new = (STDataType*)realloc(ps->a,sizeof(STDataType)*newCapacity);
  23. if (new == NULL)
  24. {
  25. printf("fail malloc\n");
  26. exit(-1);
  27. }
  28. ps->a = new;
  29. ps->capacity = newCapacity;
  30. }
  31. ps->a[ps->top++] = x;
  32. }
  33. void StackPop(ST* ps)//出栈
  34. {
  35. assert(ps);
  36. assert(ps->top > 0);
  37. --ps->top;
  38. }
  39. bool StackEmpty(ST* ps)//判断栈是否为空
  40. {
  41. assert(ps);
  42. return ps->top == 0;
  43. }
  44. STDataType StackTop(ST* ps)//取栈顶元素
  45. {
  46. assert(ps);
  47. assert(ps->top > 0);
  48. return ps->a[ps->top - 1];
  49. }
  50. int SizeStack(ST* ps)//求栈的元素数量
  51. {
  52. assert(ps);
  53. return ps->top;
  54. }

2.2 链表栈的实现

第二种:链表栈的实现

链表栈的实现在此处是运用了单链表(有哨兵位)作为载体,入栈的位置采取的是单链表的头部,即哨兵位的后面的位置,出栈出的也是哨兵位后面的节点。

Stack.h文件代码:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<stdbool.h>
  4. #include<assert.h>
  5. typedef int STDataType;
  6. typedef struct StackNode
  7. {
  8. STDataType val;
  9. struct StackNode* next;
  10. }StackNode;
  11. StackNode* StackInit();
  12. void StackDestory(StackNode* ps);
  13. void StackPush(StackNode* ps,STDataType x);
  14. void StackPop(StackNode* ps);
  15. bool StackEmpty(StackNode* ps);
  16. int SizeStack(StackNode* ps);
  17. STDataType StackTop(StackNode* ps);
  18. StackNode* BuyStackNode(STDataType x);

Stack.c文件代码:

  1. #include"Stack.h"
  2. StackNode* BuyStackNode(STDataType x)//开辟一个栈(链表的)节点
  3. {
  4. StackNode* newnode = (StackNode*)malloc(sizeof(StackNode));
  5. if (newnode == NULL)
  6. {
  7. printf("fail malloc\n");
  8. exit(-1);
  9. }
  10. newnode->next = NULL;
  11. newnode->val = x;
  12. return newnode;
  13. }
  14. StackNode* StackInit()//栈的初始化
  15. {
  16. StackNode* head = BuyStackNode(-1);
  17. return head;
  18. }
  19. void StackDestory(StackNode* ps)//栈的销毁
  20. {
  21. assert(ps);
  22. StackNode* cur = ps;
  23. while (cur)
  24. {
  25. StackNode* next = cur->next;
  26. free(cur);
  27. cur = next;
  28. }
  29. }
  30. void StackPush(StackNode* ps, STDataType x)//入栈
  31. {
  32. assert(ps);
  33. StackNode* newnode = BuyStackNode(x);
  34. StackNode* next = ps->next;
  35. ps->next = newnode;
  36. newnode->next = next;
  37. }
  38. void StackPop(StackNode* ps)//出栈
  39. {
  40. assert(ps);
  41. assert(ps->next);
  42. StackNode* pop = ps->next;
  43. ps->next = pop->next;
  44. free(pop);
  45. }
  46. bool StackEmpty(StackNode* ps)//判断栈是否为空
  47. {
  48. assert(ps);
  49. return ps->next == NULL;
  50. }
  51. int SizeStack(StackNode* ps)//求栈中有的节点的数目
  52. {
  53. assert(ps);
  54. int size = 0;
  55. StackNode* cur = ps->next;
  56. while (cur)
  57. {
  58. size++;
  59. cur = cur->next;
  60. }
  61. return size;
  62. }
  63. STDataType StackTop(StackNode* ps)//求栈顶的节点存储的元素
  64. {
  65. assert(ps);
  66. assert(ps->next);
  67. return ps->next->val;
  68. }

相关文章