当前位置:   article > 正文

链栈(栈的链式储存结构)

链栈

      链栈的操作大部分与单链表相似,只是在插入和删除上,特殊一些。

      栈顶在链表的位置:栈只是用栈顶来进行插入和删除操作,单链表有头指针,栈顶指针也是必须的,因此可以将它们两个合二为一,所以最好的把栈顶放在单链表的头部。

      由于已经有栈顶在头部,所以单链表中的头结点便失去了意义,通常对于链栈来说,是不需要头结点的

      1.我们首先定义链栈结构:

  1. struct StackNode//定义表格
  2. {
  3. SElemType data;//数据域
  4. StackNode* next;//指针域
  5. };
  6. typedef struct StackNode* LinkStackPtr;//表格指针
  7. struct LinkStack
  8. {
  9. LinkStackPtr top;//栈顶指针
  10. int count;//记录栈中的数据个数
  11. };

     

      2.创建空栈(由于不需要头结点,也不像顺序栈一样要一开始开辟出总空间,所以空栈的创建很简单,只需要建立栈顶指针并初始化,再初始化用于计数的count即可)

  1. int InitStack(LinkStack* S)//创建一个空栈
  2. {
  3. S->top = NULL;
  4. S->count = 0;
  5. return 1;
  6. }

     

      3.判断栈是否为空(链栈一般是不会出现栈满的情况的,所以我们只需要有判断链栈是否为空的函数即可)

  1. int StackEmpty(LinkStack* S)//判断栈是否为空
  2. {
  3. if (S->count == 0)
  4. return 0;
  5. return 1;
  6. }

      当用于计数的count为0就说明此时链栈为空

     

      4.进栈操作(链栈与链表主要的不同之处)

  1. void Push(LinkStack* S, SElemType e)//进栈操作
  2. {
  3. LinkStackPtr g = new StackNode;//创建新的结点
  4. g->data = e;//向新结点中输入数据
  5. g->next = S->top;
  6. S->top = g;
  7. S->count++;
  8. }

      指针top是始终指向栈顶的所以当创建的新结点作为新的栈顶后,要让top指向它

      5.输出栈中的内容(不对栈进行任何改变,只是利用while循环将其中的内容展示出来)

  1. void printStack(LinkStack* S)//输出栈中的内容
  2. {
  3. int i;
  4. LinkStackPtr p=S->top;//用来遍历栈
  5. if (S->count==0)
  6. {
  7. cout << "栈为空" << endl;
  8. return;
  9. }
  10. while (p)
  11. {
  12. cout << p->data << " ";
  13. p = p->next;
  14. }
  15. cout << endl;
  16. }

      创建一个表格指针p初始化指向栈顶以后,便重栈顶开始遍历整个链栈

      6.出栈操作(链栈与链表主要的不同之处)

  1. void Pop(LinkStack* S, SElemType* e)//出栈操作
  2. {
  3. LinkStackPtr p;//定义一个表格指针来指向待删除的栈顶的位置
  4. p = S->top;
  5. *e = S->top->data;//将要出栈的值返回到指针e指向的空间,便于知道哪一个值进行了出栈
  6. S->top = S->top->next;//指向栈顶的指针top向下移
  7. delete(p);
  8. S->count--;
  9. }

      定义SElemType* e指针是用于记录删除的数据内容,便于让用户知道删除了什么,与出栈操作关系不大。

      7.清空栈(我们用new开辟的空间是在堆区中的,必须要我们自己将内存释放,要不然会造成内存泄漏)(注意new与delete    malloc与free才是最佳拍档不能混用)

  1. void ClearStack(LinkStack* S)//清空栈
  2. {
  3. int i;
  4. LinkStackPtr p, q;//定义表格指针p,q来交替遍历
  5. p = S->top;
  6. while (p)
  7. {
  8. q = p->next;
  9. delete(p);
  10. p = q;
  11. }
  12. S->top = NULL;
  13. S->count = 0;
  14. cout << "栈清空完毕" << endl;
  15. }

      清空栈记得将计数变量count变为0,栈顶指针指向空。

全部代码展示:

头文件FUNC.h

  1. #pragma once
  2. #include<iostream>
  3. using namespace std;
  4. #include<ctime>;
  5. #define SElemType int
  6. struct StackNode//定义表格
  7. {
  8. SElemType data;//数据域
  9. StackNode* next;//指针域
  10. };
  11. typedef struct StackNode* LinkStackPtr;//表格指针
  12. struct LinkStack
  13. {
  14. LinkStackPtr top;//栈顶指针
  15. int count;//记录栈中的数据个数
  16. };
  17. int InitStack(LinkStack* S);//创建一个空栈
  18. int StackEmpty(LinkStack* S);//判断栈是否为空
  19. void Push(LinkStack* S, SElemType e);//进栈操作
  20. void printStack(LinkStack* S);//输出栈中的内容
  21. void Pop(LinkStack* S, SElemType* e);//出栈操作
  22. void ClearStack(LinkStack* S);//清空栈

源文件FUNC.cpp

  1. #include"FUNC.h"
  2. int InitStack(LinkStack* S)//创建一个空栈
  3. {
  4. S->top = NULL;
  5. S->count = 0;
  6. return 1;
  7. }
  8. int StackEmpty(LinkStack* S)//判断栈是否为空
  9. {
  10. if (S->count == 0)
  11. return 0;
  12. return 1;
  13. }
  14. void Push(LinkStack* S, SElemType e)//进栈操作
  15. {
  16. LinkStackPtr g = new StackNode;//创建新的结点
  17. g->data = e;//向新结点中输入数据
  18. g->next = S->top;
  19. S->top = g;
  20. S->count++;
  21. }
  22. void printStack(LinkStack* S)//输出栈中的内容
  23. {
  24. int i;
  25. LinkStackPtr p=S->top;//用来遍历栈
  26. if (S->count==0)
  27. {
  28. cout << "栈为空" << endl;
  29. return;
  30. }
  31. while (p)
  32. {
  33. cout << p->data << " ";
  34. p = p->next;
  35. }
  36. cout << endl;
  37. }
  38. void Pop(LinkStack* S, SElemType* e)//出栈操作
  39. {
  40. LinkStackPtr p;//定义一个表格指针来指向待删除的栈顶的位置
  41. p = S->top;
  42. *e = S->top->data;//将要出栈的值返回到指针e指向的空间,便于知道哪一个值进行了出栈
  43. S->top = S->top->next;//指向栈顶的指针top向下移
  44. delete(p);
  45. S->count--;
  46. }
  47. void ClearStack(LinkStack* S)//清空栈
  48. {
  49. int i;
  50. LinkStackPtr p, q;//定义表格指针p,q来交替遍历
  51. p = S->top;
  52. while (p)
  53. {
  54. q = p->next;
  55. delete(p);
  56. p = q;
  57. }
  58. S->top = NULL;
  59. S->count = 0;
  60. cout << "栈清空完毕" << endl;
  61. }

源文件text.cpp

  1. #include"FUNC.h"
  2. int main()
  3. {
  4. LinkStack S;//定义栈S
  5. if (InitStack(&S) == 1)
  6. {
  7. cout << "空栈创建成功" << endl;
  8. }
  9. int DBD = 1;
  10. int n;
  11. srand((unsigned int)time(NULL));//添加随机数种子
  12. cout << "欢迎来到链栈的调试" << endl;
  13. while (DBD)
  14. {
  15. system("pause");
  16. system("cls");
  17. cout << "1.输出栈的内容 2.进栈操作 3.出栈操作 4.退出程序 5.清空栈" << endl;
  18. cin >> n;
  19. switch (n)
  20. {
  21. case 1:
  22. {
  23. printStack(&S);
  24. break;
  25. }
  26. case 2:
  27. {
  28. SElemType e;
  29. e = rand() % 100 + 1;//随机产生1-100的数到e中(e用来临时储存待插入栈的数据)
  30. cout << "输入的数据为:" << e << endl;
  31. Push(&S, e);
  32. break;
  33. }
  34. case 3:
  35. {
  36. if (StackEmpty(&S) == 1)
  37. {
  38. SElemType e;
  39. Pop(&S, &e);
  40. cout << "值:" << e << "已出栈" << endl;
  41. break;
  42. }
  43. else
  44. {
  45. cout << "栈为空" << endl;
  46. break;
  47. }
  48. }
  49. case 4:
  50. {
  51. DBD = 0;
  52. cout << "谢谢使用" << endl;
  53. break;
  54. }
  55. case 5:
  56. {
  57. if (StackEmpty(&S) == 1)
  58. {
  59. ClearStack(&S);
  60. break;
  61. }
  62. else
  63. {
  64. cout << "栈为空" << endl;
  65. break;
  66. }
  67. }
  68. default:
  69. {
  70. cout << "输入不合法" << endl;
  71. break;
  72. }
  73. }
  74. }
  75. return 0;
  76. }

链栈完成。

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

闽ICP备14008679号