Chinaunix首页 | 论坛 | 博客
  • 博客访问: 488317
  • 博文数量: 111
  • 博客积分: 3146
  • 博客等级: 中校
  • 技术积分: 939
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-07 11:23
个人简介

Nathing

文章分类

全部博文(111)

文章存档

2016年(2)

2015年(1)

2014年(31)

2012年(2)

2011年(9)

2010年(36)

2009年(30)

我的朋友

分类: C/C++

2014-04-22 22:56:28

数据结构中的栈是什么

举一个简单的例子:在往箱子里面放衣物的时候,放在最上面的衣物总是我们最后放上去的;而当我们从箱子里取出衣物的时候,总是最先拿出上面的。这就是现实生活中的栈。

准确的讲,栈就是一种可以实现“先进后出(或者叫后进先出)”的存储结构。

学过数据结构的人都知道:栈可以用两种方式来实现,一种方法是用数组实现栈,这种栈成为静态栈;另外一种方法是用链表实现栈,这种栈叫做动态栈。

栈中通常存放着程序的局部变量等。栈通常有出栈和入栈操作。

栈的结构

空栈的结构:【其实就是栈顶和栈顶都指向一个无用的头结点】

数据结构之栈(C实现)

存有结点的栈结构:【栈顶指针指向栈顶结点,栈底指针指向头结点】

数据结构之栈(C实现)

栈的实现

下面是用C实现的一个栈结构的源码及详细注释:

点击(此处)折叠或打开

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<malloc.h>
  4. //定义结点结构体
  5. typedef struct Node
  6. {
  7.     int data; //内容
  8.     struct Node * pNext; //指向下一结点的指针
  9. } NODE, * PNODE; //NODE等价于struct Node, PNODE等价于struct Node *
  10. //定义栈的结构体
  11. typedef struct Stack
  12. {
  13.     PNODE pTop; //栈顶结点
  14.     PNODE pBottom; //栈底结点
  15. } STACK, * PSTACK; //STACK等价于struct Stack, PSTACK等价于struct Stack *
  16. //函数声明
  17. void initStack(PSTACK pStack); //对栈进行初始化的函数
  18. void pushStack(PSTACK pStack, int val); //入栈的函数
  19. bool popStack(PSTACK pStack, int * pVal);//出栈的函数,*pVal用来保存出栈的元素内容
  20. void traverseStack(PSTACK pStack); //遍历栈的函数
  21. bool isEmpty(PSTACK pStack); //判断栈是否为空的函数
  22. void clearStack(PSTACK pStack); //清空栈的函数
  23. int main(void)
  24. {
  25.     STACK stack; //定义一个栈变量,STACK等价于struct Stack
  26.     int val; //用来保存出栈的内容
  27.     initStack(&stack); //调用栈的初始化函数
  28.     pushStack(&stack, 10); //调用入栈的函数
  29.     pushStack(&stack, 20);
  30.     pushStack(&stack, 30);
  31.     pushStack(&stack, 50);
  32.     traverseStack(&stack); //调用遍历栈的函数
  33.     //调用出栈的函数
  34.     if(popStack(&stack, &val))
  35.     printf("出栈成功,出栈的元素值为:%d\n", val);
  36.     else
  37.     printf(" 出栈失败!");
  38.     //调用清空栈的函数
  39.     clearStack(&stack);
  40.     traverseStack(&stack); //调用遍历栈的函数
  41.     system("pause");
  42.     return 0;
  43. }

  44. void initStack(PSTACK pStack)
  45. {
  46.     //创建一个空结点,让pTop指向它
  47.     pStack->pTop = (PNODE)malloc(sizeof(NODE));
  48.     if(NULL != pStack->pTop)
  49.     {
  50.         //将pBottom也指向空节点
  51.         pStack->pBottom = pStack->pTop;
  52.         //清空空结点的指针域
  53.         pStack->pTop->pNext = NULL;
  54.     }
  55.     else //如果内存分配失败
  56.     {
  57.         printf("内存分配失败!程序退出!\n");
  58.         exit(-1);
  59.     }
  60.     return;
  61. }

  62. void pushStack(PSTACK pStack, int val)
  63. {
  64.  //动态创建一个新结点
  65.  PNODE pNew = (PNODE)malloc(sizeof(NODE));
  66.  //设置新结点的数据域的值
  67.  pNew->data = val;
  68.  //将新结点的指针域指向之前建的空节点
  69.  pNew->pNext = pStack->pTop; //pStack->pTop不能换成pStack->pBottom
  70.  //pTop指向新的结点
  71.  pStack->pTop = pNew;
  72.  return;
  73. }

  74. bool popStack(PSTACK pStack, int * pVal)
  75. {
  76.     if(isEmpty(pStack))
  77.     {
  78.         return false;
  79.     }
  80.     else
  81.     {
  82.         //先保存栈顶元素的地址,然后将pTop指向下一元素,最后释放之前栈顶元素的内存
  83.         PNODE rNode = pStack->pTop;
  84.         *pVal = rNode->data;
  85.         pStack->pTop = rNode->pNext;
  86.         free(rNode);
  87.         rNode = NULL;
  88.         return true;
  89.     }
  90. }

  91. void traverseStack(PSTACK pStack)
  92. {
  93.     //将栈顶赋给一个临时结点,因为在遍历栈的时候不能销毁栈
  94.     PNODE pNode = pStack->pTop;
  95.     //循环遍历栈,直到栈底
  96.     while(pStack->pBottom != pNode )
  97.     {
  98.         printf("%d ", pNode->data);
  99.         pNode = pNode->pNext;
  100.     }
  101.     printf("\n");
  102.     return;
  103. }

  104. bool isEmpty(PSTACK pStack)
  105. {
  106.     if(pStack->pTop == pStack->pBottom)
  107.         return true;
  108.     else
  109.         return false;
  110. }

  111. void clearStack(PSTACK pStack)
  112. {
  113.     //栈为空,则退出该函数
  114.     if(isEmpty(pStack))
  115.     {
  116.         return;
  117.     }
  118.     else
  119.     {
  120.         //两个结点指针变量用来释放栈中元素的内存
  121.         PNODE p = pStack->pTop;
  122.         PNODE q = NULL;
  123.         //循环释放内存
  124.         while(p != pStack->pBottom)
  125.         {
  126.             q = p->pNext;
  127.             free(p);
  128.             p = q;
  129.         }
  130.         //将栈顶和栈底指向同一个指针域为空的结点
  131.         pStack->pTop = pStack->pBottom;
  132.         return;
  133.     }
  134. }

栈的典型应用

生产消费模型常用栈来实现。生产者生产的东西都放入栈中,然后消费者从栈中依次取出东西,当栈顶和栈底指向都指向首结点时,生产的东西就被消耗光了。

阅读(970) | 评论(0) | 转发(0) |
0

上一篇:单链表操作

下一篇:Oracle数据导入与导出

给主人留下些什么吧!~~