当前位置:   article > 正文

数据结构之链式栈

链式栈

栈的链式存储结构简称为链栈

链式栈是通过单链表来实现的。每次入栈一个元素,向链表中添加一个节点(相当于头插法),出栈一个元素,释放一个节点。

栈顶应该放在链首还是链尾?

因为栈具有“后进先出”的特点,如果每次在链表的尾部进行插入和删除,就要遍历整个链表来找到尾节点。而在头部进行插入和删除时,只需根据头指针即可找到链表的首元素结点。而无需遍历链表。所以链式栈的出,入栈通过对链表进行头删和头插来实现。单链表中常用的的头结点也就失去了意义,因为通常对于链栈来说,是不需要头结点的。

对于链栈来说,基本不存在栈满的情况,除非内存已经没有可以使用的空间。但对于空栈来说,链表原定义是头指针指向空,那么链栈的空其实就是top == NULL.

结构定义:

  1. typedef struct Node
  2. {
  3.     int data;
  4.     struct Node *next;
  5. }Node,*Pstack;


基本操作

  1. void InitStack(Pstack ps);  //  初始化链栈
  2. bool Push(Pstack ps,int val);  // 入栈
  3. bool Pop(Pstack ps,int *rtv);   // 出栈
  4. bool GetTop(Pstack ps,int *rtv); // 得到栈顶元素
  5. bool IsEmpty(Pstack ps);  // 判空
  6. void Destroy(Pstack ps);  // 销毁栈
  7. int GetLengthStack(Pstack ps);  // 得到栈长
  8. void Show(Pstack ps);  // 打印


入栈操作

 链式栈的入栈是由单链表的头插来实现的.对于链栈的进栈push操作,假设元素值为e的新节点是s,top为栈顶指针,如下图所示

  1. bool Push(Pstack ps,int val)
  2. {
  3. assert(ps != NULL);
  4. Node *pGet = GetNode(val);
  5. pGet->next = ps->next;
  6. ps->next = pGet;
  7. return true;
  8. }

出栈操作 

假设变量p用来存储要删除的栈顶节点,将栈顶指针下移一位,最后释放p即可。

 

  1. bool Pop(Pstack ps,int *rtv)
  2. {
  3. assert(ps != NULL);
  4. if (IsEmpty(ps)) // 判空
  5. {
  6. return false;
  7. }
  8. if (rtv != NULL)
  9. {
  10. *rtv = ps->next->data; // 保存要删除的数据元素
  11. }
  12. Node *p = ps->next;
  13. ps->next = p->next;
  14. free(p);
  15. p = NULL;
  16. return true;
  17. }

对于链栈而言,如果再栈的使用过程中元素变化不可预料,有时很小有时有非常大,那么最好使用链栈。

  1. #pragma once
  2. typedef struct Node
  3. {
  4. int data;
  5. struct Node *next;
  6. }Node,*Pstack;
  7. void InitStack(Pstack ps); // 初始化链栈
  8. bool Push(Pstack ps,int val); // 入栈
  9. bool Pop(Pstack ps,int *rtv); // 出栈
  10. bool GetTop(Pstack ps,int *rtv); // 得到栈顶元素
  11. bool IsEmpty(Pstack ps); // 判空
  12. void Destroy(Pstack ps); // 销毁
  13. int GetLengthStack(Pstack ps); //得到栈长度
  14. void Show(Pstack ps); // 打印

  1. #include"LStack.h"
  2. #include<assert.h>
  3. #include<stdio.h>
  4. #include<stdlib.h>
  5. void InitStack(Pstack ps)
  6. {
  7. assert(ps != NULL);
  8. ps->next = NULL;
  9. }
  10. Node *GetNode(int val)
  11. {
  12. Node *pGet = (Node *)malloc(sizeof(Node));
  13. assert(pGet != NULL);
  14. pGet->next = NULL;
  15. pGet->data = val;
  16. return pGet;
  17. }
  18. bool Push(Pstack ps,int val)
  19. {
  20. assert(ps != NULL);
  21. Node *pGet = GetNode(val);
  22. pGet->next = ps->next;
  23. ps->next = pGet;
  24. return true;
  25. }
  26. bool Pop(Pstack ps,int *rtv)
  27. {
  28. assert(ps != NULL);
  29. if (IsEmpty(ps))
  30. {
  31. return false;
  32. }
  33. if (rtv != NULL)
  34. {
  35. *rtv = ps->next->data;
  36. }
  37. Node *p = ps->next;
  38. ps->next = p->next;
  39. free(p);
  40. p = NULL;
  41. return true;
  42. }
  43. bool GetTop(Pstack ps,int *rtv)
  44. {
  45. assert(ps != NULL);
  46. if (IsEmpty(ps))
  47. {
  48. return false;
  49. }
  50. if (rtv != NULL)
  51. {
  52. *rtv = ps->next->data;
  53. }
  54. return true;
  55. }
  56. bool IsEmpty(Pstack ps)
  57. {
  58. return ps->next == NULL;
  59. }
  60. void Destroy(Pstack ps)
  61. {
  62. assert(ps != NULL);
  63. Node *p = NULL;
  64. while (ps->next != NULL)
  65. {
  66. p = ps->next;
  67. ps->next = p->next;
  68. free(p);
  69. }
  70. p = NULL;
  71. }
  72. int GetLengthStack(Pstack ps)
  73. {
  74. assert(ps != NULL);
  75. Node *p = ps->next;
  76. int len = 0;
  77. while (p != NULL)
  78. {
  79. len++;
  80. p = p->next;
  81. }
  82. return len;
  83. }
  84. void Show(Pstack ps)
  85. {
  86. Node *p = ps->next;
  87. while (p != NULL)
  88. {
  89. printf("%d ",p->data);
  90. p = p->next;
  91. }
  92. printf("\n");
  93. }

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

闽ICP备14008679号