当前位置:   article > 正文

【栈】顺序栈知识点-内含基本操作及其说明_pop是出栈还是入栈

pop是出栈还是入栈

目录

一、概念

栈与队列

顺序栈

二、基本操作

定义

栈的初始化

判满

 判空

 扩容函数

入栈操作

出栈

 销毁

完整代码


一、概念

栈与队列

  • 栈是限定仅在表尾进行插入和删除操作的线性表
  • 队列是只允许在一端进行插入操作、而另一端进行删除操作的线性表
  • 栈:先进后出
  • 队:先进先出

  • 我们把允许插入和删除的一端称为栈顶top,另一端称为栈底
  • 不含任何数据元素的栈称为空栈
  • 首先栈是一个线性表,因此它具有线性关系,即前驱后继关系
  • 栈底是固定的,最先进栈的只能在栈底
  • 栈的插入操作push叫做进栈,也叫做入栈、压栈
  • 栈的删除操作pop叫做出栈,也叫做弹栈
  • 栈顶:数据插入和删除的一端。栈顶的当前位置是动态变化的,它由一个称为栈顶指针的位置指示器来指示。

顺序栈

栈的顺序存储其实就是线性表顺序存储的简化,我们简称为顺序栈

二、基本操作

入栈、出栈、获取栈顶元素、销毁、判空

定义

  1. //栈
  2. #define INITSIZE 10
  3. typedef int ElemType;
  4. typedef struct
  5. {
  6. ElemType* base;//存放数据的指针
  7. ElemType* top;//栈顶指针,指向当前可以存放数据的地址
  8. int stacksize;//当前总容量
  9. }SqStack, * PSqStack;//sizeof=12;12个字节

栈的初始化

栈底:动态创建内存

栈顶初始化=栈底

栈内总容量为INITSIZE

  1. //初始化
  2. void InitStack(PSqStack ps)
  3. {
  4. assert(ps != NULL);
  5. if (ps == NULL)
  6. return;
  7. ps->base = (ElemType*)malloc(INITSIZE * sizeof(ElemType));
  8. ps->top = ps->base;
  9. ps->stacksize = INITSIZE;
  10. }

判满

判满函数属于内部函数,因为外部函数一般都是动态创建内存,不需要判满。

判满条件:数据个数(即当前栈顶位置-栈底0)与容量相等时,栈满。

  1. //判满-内部函数:数据个数和容量相等
  2. static bool IsFull(PSqStack ps)
  3. {
  4. return (ps->top - ps->base) == ps->stacksize;
  5. //指针相减是俩指针之间的间隔也就是数据个数
  6. }

 判空

  1. //判空:栈顶==栈底
  2. bool IsEmpty(PSqStack ps)
  3. {
  4. return ps->top == ps->base;
  5. }

 扩容函数

base数组:扩大为原容量*2

realloc:扩容函数

扩容的实质不是在原数组后面再开辟空间,而是重新开辟原数组二倍的空间。

top:需要重新对新数组base进行指向栈顶:栈顶为栈底+原容量base+stacksize的位置

原栈容量*2:satcksize*2

栈空:ps->base==NULL;栈底为空

  1. //扩容:把容量扩大为原来二倍
  2. static void Inc(PSqStack ps)
  3. { ps->base = (ElemType*)realloc(ps->base, ps->stacksize * 2 * sizeof(ElemType));
  4. assert(ps->base != NULL);
  5. if (ps->base == NULL)
  6. return;
  7. ps->top = ps->base + ps->stacksize;
  8. ps->stacksize *= 2;
  9. }

入栈操作

先判满,如果栈满,扩容

入栈操作:元素赋值到栈顶,栈顶++

  1. //入栈
  2. bool Push(PSqStack ps, ElemType val)
  3. {
  4. if (IsFull(ps))
  5. {
  6. Inc(ps);
  7. }
  8. *(ps->top) = val;
  9. ps->top++;
  10. return true;
  11. }

出栈

函数的设计:bool来判断返回值是否为空,想要把数据带回必须用到指针,因此第二个参数设为指针类型,带回栈顶元素的值。

有两类出栈操作:

  1. //获取栈顶元素的值,但不删除
  2. bool GetTop(PSqStack ps, int* rtval)
  3. {
  4. if (IsEmpty(ps))
  5. return false;
  6. *rtval = *(ps->top - 1);//top是当前元素,要插入的位置,而栈顶元素为top-1
  7. return true;
  8. }
  9. //获取栈顶元素的值且删除
  10. bool Pop(PSqStack ps, int* rtval)
  11. {
  12. if (IsEmpty(ps))
  13. return false;
  14. *rtval = *(ps->top - 1);//top是当前元素,要插入的位置,而栈顶元素为top-1
  15. ps->top--;//删除top-1
  16. //上面两步可以合并为:*rtval = *(--ps->top - 1);
  17. return true;
  18. }

 销毁

  1. //销毁
  2. void Destory(PSqStack ps)
  3. {
  4. assert(ps != NULL);
  5. if (ps == NULL)
  6. return;
  7. free(ps->base);
  8. ps->base = NULL;
  9. ps->top = NULL;
  10. ps->stacksize = 0;
  11. }

完整代码

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<assert.h>
  4. //栈
  5. #define INITSIZE 10
  6. typedef int ElemType;
  7. typedef struct
  8. {
  9. ElemType* base;//存放数据的指针
  10. ElemType* top;//栈顶指针,指向当前可以存放数据的地址
  11. int stacksize;//当前总容量
  12. }SqStack, * PSqStack;//sizeof=12;12个字节
  13. //初始化
  14. void InitStack(PSqStack ps)
  15. {
  16. assert(ps != NULL);
  17. if (ps == NULL)
  18. return;
  19. ps->base = (ElemType*)malloc(INITSIZE * sizeof(ElemType));
  20. ps->top = ps->base;
  21. ps->stacksize = INITSIZE;
  22. }
  23. //判满-内部函数:数据个数和容量相等
  24. static bool IsFull(PSqStack ps)
  25. {
  26. return (ps->top - ps->base) == ps->stacksize;
  27. }
  28. //扩容:把容量扩大为原来二倍
  29. static void Inc(PSqStack ps)
  30. {//扩容-realloc函数:改变所指内存区域的大小
  31. ps->base = (ElemType*)realloc(ps->base, ps->stacksize * 2 * sizeof(ElemType));
  32. assert(ps->base != NULL);
  33. if (ps->base == NULL)
  34. return;
  35. ps->top = ps->base + ps->stacksize;
  36. ps->stacksize *= 2;
  37. }
  38. //入栈
  39. bool Push(PSqStack ps, ElemType val)
  40. {
  41. if (IsFull(ps))
  42. {
  43. Inc(ps);
  44. }
  45. *(ps->top) = val;
  46. ps->top++;
  47. return true;
  48. }
  49. //判空
  50. bool IsEmpty(PSqStack ps)
  51. {
  52. return ps->top == ps->base;
  53. }
  54. //获取栈顶元素的值,但不删除
  55. bool GetTop(PSqStack ps, int* rtval)
  56. {
  57. if (IsEmpty(ps))
  58. return false;
  59. *rtval = *(ps->top - 1);//top是当前元素,要插入的位置,而栈顶元素为top-1
  60. return true;
  61. }
  62. //获取栈顶元素的值且删除
  63. bool Pop(PSqStack ps, int* rtval)
  64. {
  65. if (IsEmpty(ps))
  66. return false;
  67. *rtval = *(ps->top - 1);//top是当前元素,要插入的位置,而栈顶元素为top-1
  68. ps->top--;//删除top-1
  69. //上面两步可以合并为:*rtval = *(--ps->top - 1);
  70. return true;
  71. }
  72. //销毁
  73. void Destory(PSqStack ps)
  74. {
  75. assert(ps != NULL);
  76. if (ps == NULL)
  77. return;
  78. free(ps->base);
  79. ps->base = NULL;
  80. ps->top = NULL;
  81. ps->stacksize = 0;
  82. }
  83. int main()
  84. {
  85. SqStack sta;
  86. InitStack(&sta);
  87. for (int i = 0; i < 30; i++)
  88. {
  89. Push(&sta, i);//入栈
  90. }
  91. int val;
  92. while (!IsEmpty(&sta))
  93. {
  94. Pop(&sta, &val);//出栈
  95. printf("%d\n", val);
  96. }
  97. Destory(&sta);
  98. }

测试:

 

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

闽ICP备14008679号