当前位置:   article > 正文

【数据结构】 链栈的基本操作 (C语言版)_链栈的基本操作实现(c语言)

链栈的基本操作实现(c语言)

目录

一、链栈

1、链栈的定义:

2、链栈的优缺点:

二、链栈的基本操作算法(C语言)    

1、宏定义

  2、创建结构体

3、链栈的初始化 

 4、链栈的进栈

5、链栈的出栈

6、获取栈顶元素

7、栈的遍历输出

8、链栈的判空

 9、求链栈的栈长

10、链栈的清空

11、链栈的销毁

三、链栈的基本操作完整代码(C语言)

 四、运行结果


一、链栈

1、链栈的定义:

链栈是一种栈的实现方式,它使用链表结构来实现。每个节点包含数据域和指针域,其中数据域用于存储数据,指针域用于指向下一个节点。链栈的栈顶指针指向栈顶元素,栈底指针指向栈底元素。

2、链栈的优缺点:

链栈的优点:

  1. 空间利用率高:链栈可以根据实际情况动态调整栈的大小,避免了顺序栈可能出现的内存溢出等问题。
  2. 时间复杂度低:链栈的入栈和出栈操作只需要改变栈顶指针的指向,时间复杂度为O(1),不需要像顺序栈一样进行数据的移动,具有比较高的效率。
  3. 方便进行动态扩展:链栈可以方便地进行动态扩展,当需要增加元素时,可以动态地增加存储空间;当需要减少元素时,可以释放未使用的空间。

链栈的 缺点:

  1. 需要额外的指针存储空间,因此占用的存储空间较大。
  2. 插入和删除操作需要修改指针,操作较为复杂。
  3. 无法充分利用内存的连续性优势,因为链表节点的存储位置是分散的。

二、链栈的基本操作算法(C语言)    

1、宏定义
  1. #define OK 1
  2. #define ERROR 0
  3. #define OVERFLOW -1
  4. typedef int SElemType;
  5. typedef int Status;
  2、创建结构体
  1. //创建结构体
  2. typedef struct StackNode {
  3. SElemType data;
  4. struct StackNode *next;
  5. } StackNode, *LinkStack;
3、链栈的初始化 
  1. //初始化
  2. Status InitStack(LinkStack &S) {
  3. S = NULL;
  4. return OK;
  5. }
 4、链栈的进栈
  1. //进栈
  2. Status Push(LinkStack &S, SElemType e) {//在栈顶插入元素e
  3. StackNode *p = new StackNode; //生成新结点
  4. if (!p) exit(OVERFLOW);
  5. p->data = e;
  6. p->next = S; //将新结点插入 栈顶
  7. S = p; //修改栈顶指针为p
  8. return OK;
  9. }
5、链栈的出栈
  1. //出栈
  2. Status Pop(LinkStack &S, int &e) {//删除S的栈顶元素,用e返回其值
  3. if (S == NULL) {
  4. return ERROR;
  5. }
  6. e = S->data; //将栈顶元素赋给e
  7. LinkStack p = S; //用p临时保存栈顶元素空间,以备释放
  8. S = S->next; //修改栈顶指针
  9. delete p;
  10. return OK;
  11. }
6、获取栈顶元素
  1. //获取栈顶元素
  2. Status Top(LinkStack &S, int &e) {//删除S的栈顶元素,用e返回其值
  3. if (S == NULL) {
  4. return ERROR;
  5. }
  6. e = S->data; //将栈顶元素赋给e
  7. return OK;
  8. }
7、栈的遍历输出
  1. //栈的遍历输出
  2. void StackTraverse(LinkStack S) {
  3. LinkStack p; //使用指针p辅助访问栈里元素
  4. p = S; //p初始从栈顶开始
  5. printf("从栈顶依次读出该栈中的元素值为:");
  6. while (p != NULL) {
  7. printf("%d ", p->data);
  8. p = p->next;
  9. }
  10. printf("\n");
  11. }
8、链栈的判空
  1. //判空
  2. Status stackEmpty(LinkStack S) {
  3. if (S == NULL) {如果栈顶的指针域指向空,则栈空
  4. return true;
  5. } else {
  6. return false;
  7. }
  8. }
 9、求链栈的栈长
  1. //求栈长
  2. Status stackLength(LinkStack S) {
  3. int len = 0;
  4. while (S != NULL) {
  5. len++;
  6. S = S->next;
  7. }
  8. return len;
  9. }
10、链栈的清空
  1. //清空
  2. Status ClearStack(LinkStack &S) {
  3. StackNode *p;
  4. while (S != NULL) {
  5. p = S->next;
  6. delete S;
  7. S = p;
  8. }
  9. return OK;
  10. }
11、链栈的销毁
  1. //销毁
  2. Status DestoryStack(LinkStack S) {
  3. StackNode *p;
  4. while (S) {
  5. p = S;
  6. S = S->next;
  7. delete p;
  8. }
  9. S = NULL;
  10. return OK;
  11. }

三、链栈的基本操作完整代码(C语言)

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define OK 1
  4. #define ERROR 0
  5. #define OVERFLOW -1
  6. typedef int SElemType;
  7. typedef int Status;
  8. //创建结构体
  9. typedef struct StackNode {
  10. SElemType data;
  11. struct StackNode *next;
  12. } StackNode, *LinkStack;
  13. //初始化
  14. Status InitStack(LinkStack &S) {
  15. S = NULL;
  16. return OK;
  17. }
  18. //进栈
  19. Status Push(LinkStack &S, SElemType e) {//在栈顶插入元素e
  20. StackNode *p = new StackNode; //生成新结点
  21. if (!p) exit(OVERFLOW);
  22. p->data = e;
  23. p->next = S; //将新结点插入 栈顶
  24. S = p; //修改栈顶指针为p
  25. return OK;
  26. }
  27. //出栈
  28. Status Pop(LinkStack &S, int &e) {//删除S的栈顶元素,用e返回其值
  29. if (S == NULL) {
  30. return ERROR;
  31. }
  32. e = S->data; //将栈顶元素赋给e
  33. LinkStack p = S; //用p临时保存栈顶元素空间,以备释放
  34. S = S->next; //修改栈顶指针
  35. delete p;
  36. return OK;
  37. }
  38. //获取栈顶元素
  39. Status Top(LinkStack &S, int &e) {//删除S的栈顶元素,用e返回其值
  40. if (S == NULL) {
  41. return ERROR;
  42. }
  43. e = S->data; //将栈顶元素赋给e
  44. return OK;
  45. }
  46. //获取栈顶元素
  47. Status GetTop(LinkStack S) {//返回S的栈顶元素,不修改栈顶指针
  48. if (S != NULL) {
  49. return S->data;
  50. }
  51. }
  52. //栈的遍历输出
  53. void StackTraverse(LinkStack S) {
  54. LinkStack p; //使用指针p辅助访问栈里元素
  55. p = S; //p初始从栈顶开始
  56. printf("从栈顶依次读出该栈中的元素值为:");
  57. while (p != NULL) {
  58. printf("%d ", p->data);
  59. p = p->next;
  60. }
  61. printf("\n");
  62. }
  63. //判空
  64. Status stackEmpty(LinkStack S) {
  65. if (S == NULL) {如果栈顶的指针域指向空,则栈空
  66. return true;
  67. } else {
  68. return false;
  69. }
  70. }
  71. //求栈长
  72. Status stackLength(LinkStack S) {
  73. int len = 0;
  74. while (S != NULL) {
  75. len++;
  76. S = S->next;
  77. }
  78. return len;
  79. }
  80. //清空
  81. Status ClearStack(LinkStack &S) {
  82. StackNode *p;
  83. while (S != NULL) {
  84. p = S->next;
  85. delete S;
  86. S = p;
  87. }
  88. return OK;
  89. }
  90. //销毁
  91. Status DestoryStack(LinkStack S) {
  92. StackNode *p;
  93. while (S) {
  94. p = S;
  95. S = S->next;
  96. delete p;
  97. }
  98. S = NULL;
  99. return OK;
  100. }
  101. //功能菜单
  102. int choice() {
  103. printf("==================================\n");
  104. printf(" 链栈操作功能菜单 \n");
  105. printf("1、进栈 2、出栈 3、获取栈顶元素 \n");
  106. printf("4、清空 5、销毁 6、批量进栈 \n");
  107. printf("7、判空 8、链栈的长度 \n");
  108. printf("9、打印栈内元素 10、退出程序 \n");
  109. printf("==================================\n");
  110. return 0;
  111. }
  112. int main() {
  113. LinkStack linkstack;
  114. //初始化
  115. Status rInitStack = InitStack(linkstack);
  116. if (rInitStack == OK) {
  117. printf("链栈初始化成功!\n");
  118. } else {
  119. printf("链栈初始化失败!\n");
  120. }
  121. while (1) {
  122. //功能菜单
  123. choice();
  124. int flag;
  125. printf("请输入所需的功能编号:\n");
  126. scanf("%d", &flag);
  127. switch (flag) {
  128. case 1: {//进栈
  129. Status Pushdata;
  130. printf("请输入插入元素(请在英文状态下输入例如:1): \n");
  131. scanf("%d", &Pushdata);
  132. Status rPush = Push(linkstack, Pushdata);
  133. if (rPush == OK) {
  134. printf("向链栈进栈%d成功!\n", Pushdata);
  135. } else {
  136. printf("向链栈进栈失败!\n");
  137. }
  138. }
  139. break;
  140. case 2: {//出栈
  141. Status popData;
  142. Status rPop = Pop(linkstack, popData);
  143. if (rPop == OK) {
  144. printf("向链栈出栈%d成功!\n", popData);
  145. } else {
  146. printf("向链栈出栈失败!\n");
  147. }
  148. }
  149. break;
  150. case 3: {//获取栈顶元素
  151. Status topData;
  152. Status rTop = Top(linkstack, topData);
  153. if (rTop == OK) {
  154. printf("向链栈获取栈顶元素:%d\n", topData);
  155. } else {
  156. printf("向链栈获取栈顶元素失败!\n");
  157. }
  158. // //获取栈顶元素
  159. // Status rGetTop = GetTop(linkstack);
  160. // if (rGetTop == OK) {
  161. // printf("向链栈获取栈顶元素:%d\n", topData);
  162. // } else {
  163. // printf("向链栈获取栈顶元素失败!\n");
  164. // }
  165. }
  166. break;
  167. case 4: { //清空
  168. Status rClearStack = ClearStack(linkstack);
  169. if (rClearStack == OK) {
  170. printf("链栈清空成功!\n");
  171. } else {
  172. printf("链栈清空失败!\n");
  173. }
  174. }
  175. break;
  176. case 5: {//销毁
  177. Status rDestroyStack = DestoryStack(linkstack);
  178. if (rDestroyStack == OK) {
  179. printf("链栈销毁成功!\n");
  180. } else {
  181. printf("链栈销毁失败!\n");
  182. }
  183. }
  184. break;
  185. case 6: {//批量插入
  186. int on;
  187. printf("请输入想要插入的元素个数:\n");
  188. scanf("%d", &on);
  189. SElemType array[on];
  190. for (int i = 1; i <= on; i++) {
  191. getchar();
  192. printf("向顺序栈第%d个位置插入元素为:", (i));
  193. scanf("%d", &array[i]);
  194. }
  195. for (int i = 1; i <= on; i++) {
  196. Status rPush = Push(linkstack, array[i]);
  197. if (rPush == OK) {
  198. printf("向链栈进栈%d成功!\n", array[i]);
  199. } else {
  200. printf("向链栈进栈失败!\n");
  201. }
  202. }
  203. }
  204. break;
  205. case 7: {//判空
  206. Status rStackEmpty = stackEmpty(linkstack);
  207. if (rStackEmpty == true) {
  208. printf("链栈为空栈!\n\n");
  209. } else
  210. printf("链栈不为空!\n\n");
  211. }
  212. break;
  213. case 8: {//链栈的长度
  214. Status length = stackLength(linkstack);
  215. printf("链栈的长度为:%d 。\n\n", length);
  216. }
  217. break;
  218. case 9: { //打印栈内元素
  219. StackTraverse(linkstack);
  220. }
  221. break;
  222. case 10: {//退出程序
  223. return 0;
  224. }
  225. break;
  226. default: {
  227. printf("输入错误,无此功能,请检查输入:\n\n");
  228. }
  229. }
  230. }
  231. return 1;
  232. }

 四、运行结果

 

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号