这次的数据结构是一种特殊的线性表:栈(Stack)

栈的特点是后入先出(LIFO),可见的只有栈顶的一个元素。

栈在程序中的地位非常重要,其中最重要的应用就是函数的调用。每次函数调用时都会创建该函数的一个“活动记录”( Activation Record ,或称作“帧”( Frame ))压入运行时堆栈中,用于保存函数的参数,返回值,返回指令地址,返回活动记录地址,局部变量等内容。当然,在高级语言中我们不需要手动完成这一工作,学习汇编语言时会体会到其真正过程。

下面给出笔者对于堆栈的两种实现。首先是顺序(数组)存储实现:

  1. // Stack.h
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5.  
  6. struct StackRecord;
  7. typedef struct StackRecord *Stack;
  8.  
  9. int IsEmpty(Stack S);
  10. int IsFull(Stack S);
  11. Stack CreateStack(int MaxElements);
  12. void DisposeStack(Stack S);
  13. void MakeEmpty(Stack S);
  14. void Push(ElementType X, Stack S);
  15. ElementType Top(Stack S);
  16. void Pop(Stack S);
  17. ElementType TopAndPop(Stack S);

  

  1. // Stack.c
  2.  
  3. #include "Stack.h"
  4.  
  5. struct StackRecord{
  6. int Capacity;
  7. int TopOfStack;
  8. ElementType *Array;
  9. };
  10.  
  11. int IsEmpty(Stack S)
  12. {
  13. return S->TopOfStack == -1;
  14. }
  15.  
  16. int IsFull(Stack S)
  17. {
  18. return S->TopOfStack == S->Capacity - 1;
  19. }
  20.  
  21. Stack CreateStack(int MaxElements)
  22. {
  23. Stack ret;
  24. if((ret = (Stack)malloc(sizeof(struct StackRecord))) != NULL)
  25. {
  26. ret->TopOfStack = -1;
  27. ret->Capacity = MaxElements;
  28. if((ret->Array = (ElementType*)malloc(MaxElements * sizeof(ElementType))) != NULL)
  29. return ret;
  30. free(ret);
  31. }
  32. printf("Error! Out of memory! \n");
  33. return NULL;
  34. }
  35.  
  36. void DisposeStack(Stack S)
  37. {
  38. if(S)
  39. {
  40. free(S->Array);
  41. free(S);
  42. }
  43. }
  44.  
  45. void MakeEmpty(Stack S)
  46. {
  47. S->TopOfStack = -1;
  48. }
  49.  
  50. void Push(ElementType X, Stack S)
  51. {
  52. if(IsFull(S))
  53. {
  54. printf("Error! The stack is full! \n");
  55. return;
  56. }
  57. (S->Array)[++(S->TopOfStack)] = X;
  58. }
  59.  
  60. ElementType Top(Stack S)
  61. {
  62. if(IsEmpty(S))
  63. {
  64. printf("Error! The stack is empty! \n");
  65. return 0;
  66. }
  67. return (S->Array)[(S->TopOfStack)];
  68. }
  69.  
  70. void Pop(Stack S)
  71. {
  72. if(IsEmpty(S))
  73. {
  74. printf("Error! The stack is empty! \n");
  75. return;
  76. }
  77. S->TopOfStack -= 1;
  78. }
  79.  
  80. ElementType TopAndPop(Stack S)
  81. {
  82. if(IsEmpty(S))
  83. {
  84. printf("Error! The stack is empty! \n");
  85. return 0;
  86. }
  87. return (S->Array)[(S->TopOfStack)--];
  88. }

  

接下来是链式存储实现:

  1. // Stack.h
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5.  
  6. struct _Node;
  7. typedef struct _Node Node;
  8. typedef Node *PtrToNode;
  9. typedef PtrToNode Stack;
  10.  
  11. int IsEmpty(Stack S);
  12. Stack CreateStack();
  13. void DisposeStack(Stack S);
  14. void MakeEmpty(Stack S);
  15. void Push(ElementType X, Stack S);
  16. ElementType Top(Stack S);
  17. void Pop(Stack S);

  

  1. // Stack.c
  2.  
  3. #include "Stack.h"
  4.  
  5. struct _Node
  6. {
  7. ElementType Element;
  8. struct _Node *Next;
  9. };
  10.  
  11. void print(Stack S)
  12. {
  13. for (PtrToNode p = S->Next; p; p = p->Next)
  14. {
  15. printf("%d ", p->Element);
  16. }
  17. printf("\n");
  18. }
  19.  
  20. int main()
  21. {
  22. Stack s = CreateStack();
  23. print(s);
  24. Pop(s);
  25. printf("%d", Top(s));
  26. Push(2, s);
  27. Push(3, s);
  28. Push(5, s);
  29. print(s);
  30. Pop(s);
  31. print(s);
  32. MakeEmpty(s);
  33. print(s);
  34. DisposeStack(s);
  35. getchar();
  36. getchar();
  37. }
  38.  
  39. int IsEmpty(Stack S)
  40. {
  41. return S->Next == NULL;
  42. }
  43.  
  44. Stack CreateStack()
  45. {
  46. Stack ret;
  47. if ((ret = (Stack)malloc(sizeof(Node))) != NULL)
  48. {
  49. ret->Next = NULL;
  50. return ret;
  51. }
  52. printf("Error! Out of memory! \n");
  53. return 0;
  54. }
  55.  
  56. void DisposeStack(Stack S)
  57. {
  58. PtrToNode p = S;
  59. while (S != NULL)
  60. {
  61. S = S->Next;
  62. free(p);
  63. p = S;
  64. }
  65. }
  66.  
  67. void MakeEmpty(Stack S)
  68. {
  69. if (S == NULL)
  70. {
  71. printf("Error! It's not a Stack!\n");
  72. return;
  73. }
  74. while (!IsEmpty(S))
  75. Pop(S);
  76. }
  77.  
  78. void Push(ElementType X, Stack S)
  79. {
  80. PtrToNode t;
  81. if ((t = (PtrToNode)malloc(sizeof(Node))) != NULL)
  82. {
  83. t->Element = X;
  84. t->Next = S->Next;
  85. S->Next = t;
  86. return;
  87. }
  88. printf("Error! Out of memory! \n");
  89. }
  90.  
  91. ElementType Top(Stack S)
  92. {
  93. if (S->Next == NULL)
  94. {
  95. printf("Error! The stack is empty! \n");
  96. return 0;
  97. }
  98. return S->Next->Element;
  99. }
  100.  
  101. void Pop(Stack S)
  102. {
  103. PtrToNode p = S->Next;
  104. if (p == NULL)
  105. {
  106. printf("Error! The stack is empty! \n");
  107. return;
  108. }
  109. S->Next = p->Next;
  110. free(p);
  111. }

 以上就是堆栈的两种实现。由于较为简单,不再给出测试样例。

《数据结构与算法分析——C语言描述》ADT实现(NO.01) : 栈(Stack)的更多相关文章

  1. 《数据结构与算法分析——C语言描述》ADT实现(NO.00) : 链表(Linked-List)

    开始学习数据结构,使用的教材是机械工业出版社的<数据结构与算法分析——C语言描述>,计划将书中的ADT用C语言实现一遍,记录于此.下面是第一个最简单的结构——链表. 链表(Linked-L ...

  2. 数据结构与算法分析——C语言描述 第三章的单链表

    数据结构与算法分析--C语言描述 第三章的单链表 很基础的东西.走一遍流程.有人说学编程最简单最笨的方法就是把书上的代码敲一遍.这个我是头文件是照抄的..c源文件自己实现. list.h typede ...

  3. 最小正子序列(序列之和最小,同时满足和值要最小)(数据结构与算法分析——C语言描述第二章习题2.12第二问)

    #include "stdio.h" #include "stdlib.h" #define random(x) (rand()%x) void creat_a ...

  4. C语言学习书籍推荐《数据结构与算法分析:C语言描述(原书第2版)》下载

    维斯 (作者), 冯舜玺 (译者) <数据结构与算法分析:C语言描述(原书第2版)>内容简介:书中详细介绍了当前流行的论题和新的变化,讨论了算法设计技巧,并在研究算法的性能.效率以及对运行 ...

  5. 《数据结构与算法分析-Java语言描述》 分享下载

    书籍信息 书名:<数据结构与算法分析-Java语言描述> 原作名:Data Structures and Algorithm Analysis in Java 作者: 韦斯 (Mark A ...

  6. 读书笔记:《数据结构与算法分析Java语言描述》

    目录 第 3 章 表.栈和队列 3.2 表 ADT 3.2.1 表的简单数组实现 3.2.2 简单链表 3.3 Java Collections API 中的表 3.3.1 Collection 接口 ...

  7. 《数据结构与算法分析——C语言描述》ADT实现(NO.03) : 二叉搜索树/二叉查找树(Binary Search Tree)

    二叉搜索树(Binary Search Tree),又名二叉查找树.二叉排序树,是一种简单的二叉树.它的特点是每一个结点的左(右)子树各结点的元素一定小于(大于)该结点的元素.将该树用于查找时,由于二 ...

  8. 《数据结构与算法分析——C语言描述》ADT实现(NO.05) : 散列(Hash)

    散列(Hash)是一种以常数复杂度实现查找功能的数据结构.它将一个关键词Key,通过某种映射(哈希函数)转化成索引值直接定位到相应位置. 实现散列有两个关键,一是哈希函数的选择,二是冲突的处理. 对于 ...

  9. 《数据结构与算法分析——C语言描述》ADT实现(NO.04) : AVL树(AVL-Tree)

    上次我们已经实现了普通的二叉查找树.利用二叉查找树,可以用O(logN)高度的树状结构存储和查找数据,提高了存储和查找的效率. 然而,考虑一种极端情形:依次插入1,2,3,4,5,6,7,8,9九个元 ...

随机推荐

  1. PAT甲级——A1109 Group Photo【25】

    Formation is very important when taking a group photo. Given the rules of forming K rows with Npeopl ...

  2. 通过JBOSS服务器来实现JMS消息传送

    首先必须启动JBOSS服务器,以便于充当JMS传递消息的中间键: JBOSS消息发送端: package test; import java.util.concurrent.CountDownLatc ...

  3. 使用virtualenv发布Python程序

    客户环境不能上网,开始想把所有依赖包下载下来,进入客户环境进行安装.但为了避免出差,部署工作交给其他同事了,我想还是需要更简单的方式. 实验了一下virtualenv是可以的 1. 创建一个新的环境( ...

  4. CentOS7-Minimal安装MySQL服务

    CentOS7默认安装的是Mariadb而不是mysql,而Mariadb是mysql的一个分支, 安装mysql会覆盖Mariadb 一.下载MySQL官方的 Yum Repository [roo ...

  5. js 禁止/允许页面滚动

    参考:https://blog.csdn.net/huangfu_chunfeng/article/details/46429997         https://www.cnblogs.com/w ...

  6. spark 应用场景1-求年龄平均值

    原文引自:http://blog.csdn.net/fengzhimohan/article/details/78535143 该案例中,我们将假设我们需要统计一个 10 万人口的所有人的平均年龄,当 ...

  7. Ubuntu usb设备端口号绑定

    1.将串口设备插入USB口,通过lsusb查看端口信息.例如: ID 1a86:7523 表示usb设备的ID(这个ID由芯片制造商设置,可以唯一表示该设备) 1a86 usb_device_desc ...

  8. vuex结合vue-cookies的使用

    一.创建vuex import Vue from 'vue' import Vuex from 'vuex' import cookie from "vue-cookies" Vu ...

  9. JS Math.sin() 与 Math.cos() 用法 (含圆上每个点的坐标)

    Math.sin(x)      x 的正玄值.返回值在 -1.0 到 1.0 之间: Math.cos(x)    x 的余弦值.返回的是 -1.0 到 1.0 之间的数: 这两个函数中的X 都是指 ...

  10. System.Web.Mvc.FileContentResult.cs

    ylbtech-System.Web.Mvc.FileContentResult.cs 1.程序集 System.Web.Mvc, Version=5.2.3.0, Culture=neutral, ...