当前位置:   article > 正文

C语言 数据结构 之 链式栈_c语言链栈

c语言链栈

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

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

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

1. 链式栈的结点结构

        链式栈是有单链表来实现的,所以与单链表的结点结构相同。由数据域和指向下一个结点的指针域(next域)组成。

  1. //链式结构 =数据域+指针域
  2. struct Node
  3. {
  4. int data;
  5. struct Node *next;
  6. };

2. 链式栈的初始化

        与单链表的初始化相同,可以设置函数单独先对每个节点进行初始化操作。

 

  1. // 2、创建节点 为插入做准备,学习数据的时候,一定要把功能划分明确
  2. struct Node *createNode(int data)
  3. {
  4. struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
  5. newNode->data = data;
  6. newNode->next = NULL;
  7. return newNode; 返回指针变量
  8. }

 3、表头插入
//  插在头结点之后  插队插入,不能越过头结点
//  插队插入,不能越过头结点

  1. void insertNodeByHead(struct Node *headNode, int data) //表头法插入
  2. {
  3. // 1、插入的新节点的定义变量
  4. struct Node* newNode = createNode(data);
  5. // 2、 插在头结点之后 插队插入,不能越过头结点
  6. newNode->next = headNode->next;
  7. headNode->next = newNode;
  8. }

4、打印,浏览信息

  1. void printList(struct Node *headNode) //打印,浏览信息
  2. {
  3. // 有表头,要从第二个节点开始打印
  4. struct Node *pMove = headNode->next;
  5. while (pMove != NULL)
  6. {
  7. printf("%d\t", pMove->data);
  8. pMove = pMove->next;
  9. }
  10. printf("\n");
  11. }

5、栈操作

  1. struct stack
  2. {
  3. struct Node* stackTop; // 用栈顶指针表示整个链表
  4. int size; // 数据结构中的万金油 记录数据结构中元素的个数
  5. };
  6. // 1、指针----->指针变量 动态内存申请
  7. // 2、初始化变量
  8. // 3、返回变量
  9. struct stack *createStack()
  10. {
  11. //1、指针----->指针变量
  12. struct stack *mystack = (struct stack*)malloc(sizeof(struct stack));
  13. //2、初始化变量
  14. mystack->size = 0;
  15. mystack->stackTop = NULL;
  16. //3、返回变量
  17. return mystack;
  18. }
  19. //入栈函数
  20. /* 将指定的数据压入栈 */
  21. void push(struct stack *mystack, int data)
  22. {
  23. //入栈操作----->链表的表头插入
  24. //无表头的链表
  25. struct Node *newNode = createNode(data);
  26. newNode->next = mystack->stackTop; //新来元素的下一个next指向栈顶指针,连续存储
  27. mystack->stackTop = newNode; //用栈顶指针 永远指向新来的元素
  28. mystack->size++;
  29. }
  30. int getTop(struct stack *mystack) //获取栈顶元素
  31. {
  32. if (mystack->size == 0)
  33. {
  34. printf("栈为空!,无法获取");
  35. system("pause");
  36. return mystack->size;
  37. }
  38. return mystack->stackTop->data;
  39. }
  40. void pop(struct stack *mystack)
  41. {
  42. if (mystack->size == 0)
  43. {
  44. printf("栈为空!,无法出栈");
  45. system("pause");
  46. }
  47. else
  48. {
  49. // 无表头的链表进行删除
  50. struct Node *nextNode = mystack->stackTop->next; //先保存记录
  51. free(mystack->stackTop); //将原先节点的占用的内存释放
  52. mystack->stackTop = nextNode;
  53. mystack->size--;
  54. }
  55. }
  56. int empty(struct stack *mystack)
  57. {
  58. if (mystack->size == 0)
  59. {
  60. return 0;
  61. }
  62. else
  63. return 1;//返回1,代表栈不为空
  64. }

6、总代码

  1. /*
  2. 栈的应用
  3. // 1、寻路算法 迷宫
  4. // 2、悔棋退步问题
  5. // 3、了解栈 FILO 先进后出 先存后拿
  6. // 4、属于自己的编译方式
  7. // 5、解决问题的能力
  8. */
  9. #include<stdio.h>
  10. #include<stdlib.h>
  11. //链式结构 =数据域+指针域
  12. struct Node
  13. {
  14. int data;
  15. struct Node *next;
  16. };
  17. // 2、创建节点 为插入做准备,学习数据的时候,一定要把功能划分明确
  18. struct Node *createNode(int data)
  19. {
  20. struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
  21. newNode->data = data;
  22. newNode->next = NULL;
  23. return newNode; 返回指针变量
  24. }
  25. // 3、表头插入
  26. // 插在头结点之后 插队插入,不能越过头结点
  27. // 插队插入,不能越过头结点
  28. // 函数参数设计是具有含义的:插入那个链表??插入的新节点的定义变量
  29. void insertNodeByHead(struct Node *headNode, int data) //表头法插入
  30. {
  31. // 1、插入的新节点的定义变量
  32. struct Node* newNode = createNode(data);
  33. // 2、 插在头结点之后 插队插入,不能越过头结点
  34. newNode->next = headNode->next;
  35. headNode->next = newNode;
  36. }
  37. // 4、表尾插入
  38. void insertNodeByTail(struct Node *headNode, int data)
  39. {
  40. struct Node* newNode = createNode(data);
  41. struct Node* tailNode = headNode;
  42. while (tailNode->next != NULL)
  43. {
  44. tailNode = tailNode->next;
  45. }
  46. tailNode->next = newNode;
  47. }
  48. void printList(struct Node *headNode) //打印,浏览信息
  49. {
  50. // 有表头,要从第二个节点开始打印
  51. struct Node *pMove = headNode->next;
  52. while (pMove != NULL)
  53. {
  54. printf("%d\t", pMove->data);
  55. pMove = pMove->next;
  56. }
  57. printf("\n");
  58. }
  59. /****************************栈操作********************/
  60. // 用结构体封装一个栈
  61. struct stack
  62. {
  63. struct Node* stackTop; // 用栈顶指针表示整个链表
  64. int size; // 数据结构中的万金油 记录数据结构中元素的个数
  65. };
  66. // 1、指针----->指针变量 动态内存申请
  67. // 2、初始化变量
  68. // 3、返回变量
  69. struct stack *createStack()
  70. {
  71. //1、指针----->指针变量
  72. struct stack *mystack = (struct stack*)malloc(sizeof(struct stack));
  73. //2、初始化变量
  74. mystack->size = 0;
  75. mystack->stackTop = NULL;
  76. //3、返回变量
  77. return mystack;
  78. }
  79. //入栈函数
  80. /* 将指定的数据压入栈 */
  81. void push(struct stack *mystack, int data)
  82. {
  83. //入栈操作----->链表的表头插入
  84. //无表头的链表
  85. struct Node *newNode = createNode(data);
  86. newNode->next = mystack->stackTop; //新来元素的下一个next指向栈顶指针,连续存储
  87. mystack->stackTop = newNode; //用栈顶指针 永远指向新来的元素
  88. mystack->size++;
  89. }
  90. int getTop(struct stack *mystack) //获取栈顶元素
  91. {
  92. if (mystack->size == 0)
  93. {
  94. printf("栈为空!,无法获取");
  95. system("pause");
  96. return mystack->size;
  97. }
  98. return mystack->stackTop->data;
  99. }
  100. void pop(struct stack *mystack)
  101. {
  102. if (mystack->size == 0)
  103. {
  104. printf("栈为空!,无法出栈");
  105. system("pause");
  106. }
  107. else
  108. {
  109. // 无表头的链表进行删除
  110. struct Node *nextNode = mystack->stackTop->next; //先保存记录
  111. free(mystack->stackTop); //将原先节点的占用的内存释放
  112. mystack->stackTop = nextNode;
  113. mystack->size--;
  114. }
  115. }
  116. int empty(struct stack *mystack)
  117. {
  118. if (mystack->size == 0)
  119. {
  120. return 0;
  121. }
  122. else
  123. return 1;//返回1,代表栈不为空
  124. }
  125. int main()
  126. {
  127. //1、链表的实质:结构体变量 和结构体变量 连接在一起
  128. struct stack *mystack = createStack();
  129. push(mystack, 1);
  130. push(mystack, 2);
  131. push(mystack, 3);
  132. push(mystack, 4);
  133. push(mystack, 5);
  134. while (empty(mystack))
  135. {
  136. printf("%d---->\t", getTop(mystack));
  137. pop(mystack);
  138. }
  139. printf("\n");
  140. system("pause");
  141. return 0;
  142. }

将1 2 3 4 5 入栈,然后出栈

 

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

闽ICP备14008679号