当前位置:   article > 正文

[数据结构-5] 详解栈以及两种存储结构的C语言实现_c语言中栈的存储结构

c语言中栈的存储结构

目录

认识栈

三种物理结构

1.顺序储存结构

2.链式储存结构

3.共享栈

出栈顺序的特点

C语言实现

顺序栈

链式栈

共享栈


认识栈

栈也是一种线性的逻辑结构, 和顺序表与普通链表不同的是他的操作(运算)不同

复习一下数据结构的三要素: 逻辑结构, 物理(储存结构), 操作(运算)

栈有两端: 栈顶和栈底, 只能在栈顶进行增加(入栈)和删除(出栈)

所以栈可以看成是一种操作受限的线性表

栈的特点是先进后出

三种物理结构

1.顺序储存结构

用一个数组实现栈, 用一个额外的指针指向栈顶(一般把栈底固定)

2.链式储存结构

用链表实现栈, 链表的第一个节点表示栈顶, 最后一个节点表示栈底, 只在链表的头部进行删除和增加

3.共享栈

用一个长为n数组a实现两个栈, 这两个栈的栈顶分别在a[-1]和a[n](指向栈底说明是空栈), 栈顶向中间延伸, 只有当两个栈顶相距为1时栈才满, 更好地利用了空间

出栈顺序的特点

栈方面的考察点经常是给出入栈顺序, 判断某个出栈顺序是否存在

一般这样考虑:

例如入栈为1,2,3,4....n

  • 如果第1个出栈元素是n, 那么不用想了, 它是先全部入栈, 再全部出栈, 出栈顺序是n,n-1,n-2....1
  • 如果第2个出栈元素是n, 那么第1个出栈元素可以是任意一个, 但是第3个出栈元素只能是n-1或者n-2
  • 如果第3个出栈元素是n, 那么第1个和第2个出栈元素可以是任意一个, 但是第4个出栈元素只能是n-1,n-2,n-3
  • 以此类推...

C语言实现

顺序栈

  1. /**
  2. * @file sequence_stack.c
  3. * @author xiaoxiao (you@domain.com)
  4. * @brief 顺序栈
  5. * @version 0.1
  6. * @date 2022-03-05
  7. *
  8. * @copyright Copyright (c) 2022
  9. *
  10. */
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <stdbool.h>
  14. #define MaxSize 10
  15. typedef struct Stack {
  16. int* pData; // 数据
  17. int top; // 栈顶位置(-1表示空栈, 0表示当前栈有一个元素)
  18. }Stack;
  19. typedef Stack* PStack;
  20. /**
  21. * @brief 初始化一个栈
  22. *
  23. * @return PStack 栈指针
  24. */
  25. PStack initailStack(){
  26. PStack pStack = (PStack) malloc (sizeof(PStack));
  27. if(pStack == NULL){
  28. printf("no more momery");
  29. exit(1);
  30. }
  31. pStack -> pData = (int*) malloc (MaxSize * sizeof(int));
  32. if(pStack -> pData == NULL){
  33. printf("no more momery");
  34. exit(1);
  35. }
  36. pStack -> top = -1; // 空栈
  37. return pStack;
  38. }
  39. /**
  40. * @brief 元素入栈
  41. *
  42. * @param pStack 栈指针
  43. * @param data 入栈元素
  44. * @return true 入栈成功
  45. * @return false 入栈失败
  46. */
  47. bool push(PStack pStack, int data){
  48. if(pStack -> top == MaxSize - 1){
  49. printf("栈已满, 无法进栈\n");
  50. return false;
  51. }
  52. pStack -> pData[pStack -> top ++ + 1] = data;
  53. return true;
  54. }
  55. /**
  56. * @brief 元素出栈
  57. *
  58. * @param pStack 栈指针
  59. * @return int 出栈元素
  60. */
  61. int pop(PStack pStack){
  62. if(pStack -> top == -1){
  63. printf("空栈不能出栈");
  64. return false;
  65. }
  66. return pStack -> pData[-- pStack -> top + 1];
  67. }
  68. /**
  69. * @brief 打印栈中元素
  70. *
  71. * @param pStack 栈指针
  72. * @return true 非空栈,可以打印
  73. * @return false 不是空栈
  74. */
  75. bool printStack(PStack pStack){
  76. if(pStack -> top == -1){
  77. printf("空栈不能打印\n");
  78. return false;
  79. }
  80. printf("自栈底打印元素: ");
  81. for(int i = 0; i <= pStack -> top; i ++){
  82. printf("%d ", pStack -> pData[i]);
  83. }
  84. printf("\n");
  85. return true;
  86. }
  87. /**
  88. * @brief 销毁栈, 并释放栈空间
  89. *
  90. * @param pStack
  91. */
  92. void destoryStack(PStack pStack){
  93. free(pStack -> pData);
  94. free(pStack);
  95. }
  96. int main(){
  97. printf("--------------------\n");
  98. PStack pStack = initailStack();
  99. push(pStack, 1);
  100. push(pStack, 10);
  101. push(pStack, 4);
  102. printStack(pStack);
  103. destoryStack(pStack);
  104. printf("--------------------");
  105. return 0;
  106. }

链式栈

链式栈这里引用了我以前的写的链表的linked_list.h头文件

  1. /**
  2. * @file linked_stack.c
  3. * @author xiaoxiao (you@domain.com)
  4. * @brief 链式栈
  5. * @version 0.1
  6. * @date 2022-03-05
  7. *
  8. * @copyright Copyright (c) 2022
  9. *
  10. */
  11. #include <stdio.h>
  12. #include "linked_list.h"
  13. /**
  14. * @brief 初始化一个链式栈
  15. *
  16. * @return PNode 头结点
  17. */
  18. PNode initailStack(){
  19. return initalList();
  20. }
  21. /**
  22. * @brief 元素入栈
  23. *
  24. * @param pStack 栈指针
  25. * @param data 入栈元素
  26. * @return true 入栈成功
  27. * @return false 入栈失败
  28. */
  29. bool push(PNode pHead, int data){
  30. return insertByIndex(pHead, 1, data);
  31. }
  32. /**
  33. * @brief 元素出栈
  34. *
  35. * @param pStack 栈指针
  36. * @return int 出栈元素
  37. */
  38. int pop(PNode pHead){
  39. int x;
  40. if(pHead -> next != NULL){
  41. x = pHead -> next -> data;
  42. deleteByIndex(pHead, 1);
  43. return x;
  44. }
  45. printf("空栈无法出栈\n");
  46. return -1;
  47. }
  48. /**
  49. * @brief 打印栈中元素
  50. *
  51. * @param pStack 栈指针
  52. * @return true 非空栈,可以打印
  53. * @return false 不是空栈
  54. */
  55. bool printStack(PNode pHead){
  56. if(pHead -> next == NULL){
  57. printf("空栈不能打印\n");
  58. return false;
  59. }
  60. PNode pCurrent = pHead;
  61. printf("自栈底打印元素: ");
  62. int l = getLength(pHead);
  63. int* data = (int*) malloc (l * sizeof(int));
  64. int i = 0;
  65. while (pCurrent -> next != NULL) {
  66. data[i ++] = pCurrent -> next -> data;
  67. pCurrent = pCurrent -> next;
  68. }
  69. for(i = 1; i <= l; i++)
  70. printf("%d ", data[l - i]);
  71. printf("\n");
  72. return true;
  73. }
  74. /**
  75. * @brief 销毁栈, 并释放栈空间
  76. *
  77. * @param pStack
  78. */
  79. void destoryStack(PNode pHead){
  80. destroyList(pHead);
  81. }
  82. int main(){
  83. printf("-----------------\n");
  84. PNode pHead = initailStack();
  85. push(pHead, 1);
  86. push(pHead, 4);
  87. pop(pHead);
  88. printStack(pHead);
  89. destoryStack(pHead);
  90. printf("-----------------");
  91. return 0;
  92. }

共享栈

  1. /**
  2. * @file shared_stack.c
  3. * @author xiaoxiao (you@domain.com)
  4. * @brief 共享栈
  5. * @version 0.1
  6. * @date 2022-03-06
  7. *
  8. * @copyright Copyright (c) 2022
  9. *
  10. */
  11. #include <math.h>
  12. #include <stdbool.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #define MaxSize 20 // 总栈长
  16. typedef struct Stack {
  17. int* pData; // 数据
  18. int leftTop; // 左栈顶(-1表示空栈, 0表示当前栈有一个元素)
  19. int rightTop; // 右栈顶
  20. } Stack;
  21. typedef Stack* PStack;
  22. /**
  23. * @brief 初始化一个栈
  24. *
  25. * @return PStack 栈指针
  26. */
  27. PStack initailStack() {
  28. PStack pStack = (PStack)malloc(sizeof(PStack));
  29. if (pStack == NULL) {
  30. printf("no more momery");
  31. exit(1);
  32. }
  33. pStack->pData = (int*)malloc(MaxSize * sizeof(int));
  34. if (pStack->pData == NULL) {
  35. printf("no more momery");
  36. exit(1);
  37. }
  38. pStack->leftTop = -1; // 左栈顶
  39. pStack->rightTop = MaxSize; // 右栈顶
  40. return pStack;
  41. }
  42. /**
  43. * @brief 元素入栈
  44. *
  45. * @param pStack 栈指针
  46. * @param data 入栈元素,非负数就是向左入栈,负数就是向后入栈
  47. * @return true 入栈成功
  48. * @return false 入栈失败
  49. */
  50. bool push(PStack pStack, int data) {
  51. if (pStack->leftTop + 1 == pStack->rightTop) {
  52. printf("栈已满, 无法进栈\n");
  53. return false;
  54. }
  55. if (data >= 0)
  56. pStack->pData[pStack->leftTop++ + 1] = data;
  57. else
  58. pStack->pData[pStack->rightTop-- - 1] = abs(data);
  59. return true;
  60. }
  61. /**
  62. * @brief 元素出栈
  63. *
  64. * @param pStack 栈指针
  65. * @param side 哪一侧的元素,true:左侧,false:右侧
  66. * @return int 出栈元素
  67. */
  68. int pop(PStack pStack, bool side) {
  69. if (side) {
  70. if (pStack->leftTop == -1) {
  71. printf("空栈不能出栈\n");
  72. return -1;
  73. }
  74. return pStack->pData[pStack->leftTop--];
  75. }
  76. else {
  77. if (pStack->rightTop == MaxSize) {
  78. printf("空栈不能出栈\n");
  79. return -1;
  80. }
  81. return pStack->pData[pStack->rightTop++];
  82. }
  83. }
  84. /**
  85. * @brief 打印栈中元素
  86. *
  87. * @param pStack 栈指针
  88. * @return true 非空栈,可以打印
  89. * @return false 不是空栈
  90. */
  91. void printStack(PStack pStack) {
  92. if (pStack->leftTop == -1)
  93. printf("左栈为空,不能打印\n");
  94. else {
  95. printf("自左栈底打印元素: ");
  96. for (int i = 0; i <= pStack->leftTop; i++) {
  97. printf("%d ", pStack->pData[i]);
  98. }
  99. printf("\n");
  100. }
  101. if (pStack->rightTop == MaxSize)
  102. printf("右栈为空,不能打印\n");
  103. else {
  104. printf("自右栈底打印元素: ");
  105. for (int i = MaxSize - 1; i >= pStack->leftTop; i--) {
  106. printf("%d ", pStack->pData[i]);
  107. }
  108. printf("\n");
  109. }
  110. }
  111. /**
  112. * @brief 销毁栈, 并释放栈空间
  113. *
  114. * @param pStack
  115. */
  116. void destoryStack(PStack pStack) {
  117. free(pStack->pData);
  118. free(pStack);
  119. }
  120. int main() {
  121. printf("--------------------\n");
  122. PStack pStack = initailStack();
  123. push(pStack, 1);
  124. push(pStack, -10);
  125. push(pStack, 4);
  126. printStack(pStack);
  127. destoryStack(pStack);
  128. printf("--------------------");
  129. return 0;
  130. }

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

闽ICP备14008679号