Chinaunix首页 | 论坛 | 博客
  • 博客访问: 269390
  • 博文数量: 138
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 971
  • 用 户 组: 普通用户
  • 注册时间: 2015-03-03 10:05
文章分类

全部博文(138)

文章存档

2016年(1)

2015年(137)

我的朋友

分类: C/C++

2015-04-01 20:09:39

  • 数据结构中的栈是什么

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

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

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

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

  • 栈的结构

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

 

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

 

  • 栈的实现

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

C代码  收藏代码
  1. #include  
  2. #include  
  3. #include  
  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.   
  45. void initStack(PSTACK pStack)  
  46. {  
  47.  //创建一个空结点,让pTop指向它  
  48.  pStack->pTop = (PNODE)malloc(sizeof(NODE));  
  49.  if(NULL != pStack->pTop)  
  50.  {  
  51.   //将pBottom也指向空节点  
  52.   pStack->pBottom = pStack->pTop;  
  53.   //清空空结点的指针域  
  54.   pStack->pTop->pNext = NULL;  
  55.   
  56.  }  
  57.  else      //如果内存分配失败  
  58.  {  
  59.   printf("内存分配失败!程序退出!\n");  
  60.   exit(-1);  
  61.  }  
  62.  return;  
  63. }  
  64.   
  65. void pushStack(PSTACK pStack, int val)  
  66. {  
  67.  //动态创建一个新结点  
  68.  PNODE pNew = (PNODE)malloc(sizeof(NODE));  
  69.  //设置新结点的数据域的值  
  70.  pNew->data = val;  
  71.  //将新结点的指针域指向之前建的空节点  
  72.  pNew->pNext = pStack->pTop;   //pStack->pTop不能换成pStack->pBottom  
  73.  //pTop指向新的结点  
  74.  pStack->pTop = pNew;  
  75.  return;  
  76. }  
  77.   
  78. bool popStack(PSTACK pStack, int * pVal)  
  79. {  
  80.  if(isEmpty(pStack))  
  81.  {  
  82.   return false;  
  83.  }  
  84.  else  
  85.  {  
  86.   //先保存栈顶元素的地址,然后将pTop指向下一元素,最后释放之前栈顶元素的内存  
  87.   PNODE rNode = pStack->pTop;  
  88.   *pVal = rNode->data;  
  89.   pStack->pTop = rNode->pNext;  
  90.   free(rNode);  
  91.   rNode = NULL;  
  92.   return true;  
  93.  }  
  94.   
  95. }  
  96.   
  97. void traverseStack(PSTACK pStack)  
  98. {  
  99.  //将栈顶赋给一个临时结点,因为在遍历栈的时候不能销毁栈  
  100.  PNODE pNode = pStack->pTop;  
  101.  //循环遍历栈,直到栈底  
  102.  while(pStack->pBottom != pNode )  
  103.  {  
  104.   printf("%d  ", pNode->data);  
  105.   pNode = pNode->pNext;  
  106.  }  
  107.  printf("\n");  
  108.  return;  
  109. }  
  110.   
  111. bool isEmpty(PSTACK pStack)  
  112. {  
  113.  if(pStack->pTop == pStack->pBottom)  
  114.   return true;  
  115.  else  
  116.   return false;  
  117. }  
  118.   
  119. void clearStack(PSTACK pStack)  
  120. //栈为空,则退出该函数  
  121.  if(isEmpty(pStack))  
  122.  {  
  123.   return;  
  124.  }  
  125.  else  
  126.  {   
  127.   //两个结点指针变量用来释放栈中元素的内存  
  128.   PNODE p = pStack->pTop;  
  129.   PNODE q = NULL;  
  130.   //循环释放内存  
  131.   while(p != pStack->pBottom)  
  132.   {  
  133.    q = p->pNext;  
  134.    free(p);  
  135.    p = q;  
  136.   }  
  137.   //将栈顶和栈底指向同一个指针域为空的结点  
  138.   pStack->pTop = pStack->pBottom;  
  139.   return;  
  140.  }  
  141. }  
阅读(681) | 评论(0) | 转发(0) |
0

上一篇:链表头

下一篇:android反编译

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