相对于顺序栈,链表栈的内存使用更加灵活,因为链表栈的内存空间是通过动态分配获得的,它不需要在创建时确定其大小,而是根据需要逐个分配节点。当需要压入一个新的元素时,只需要分配一个新的节点,并将其插入到链表的头部;当需要弹出栈顶元素时,只需要删除链表头部的节点,并释放其所占用的内存空间即可。由于链表栈的空间利用率更高,因此在实际应用中,链表栈通常比顺序栈更受欢迎。

在实现上,链表栈通过使用malloc函数动态开辟节点内存空间来实现入栈操作,在释放时使用free函数释放节点内存空间来实现出栈操作,这使得链表栈相对于顺序栈更加节约存储空间,也更加容易实现。

读者需自行创建头文件linkstack.h并拷贝如下链表栈代码实现;

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. struct StackNode
  5. {
  6. struct StackNode *next;
  7. };
  8. struct LStack
  9. {
  10. struct StackNode header;
  11. int size;
  12. };
  13. typedef void* LinkStack;
  14. // 初始化
  15. LinkStack InitLinkStack()
  16. {
  17. struct LStack *stack = malloc(sizeof(struct LStack));
  18. if (NULL == stack)
  19. {
  20. return NULL;
  21. }
  22. stack->header.next = NULL;
  23. stack->size = 0;
  24. return stack;
  25. }
  26. // 入栈
  27. void PushLinkStack(LinkStack stack, void *data)
  28. {
  29. if (NULL == stack || NULL == data)
  30. {
  31. return;
  32. }
  33. // 先将头指针进行强转
  34. struct LStack *ls = (struct LStack *)stack;
  35. // 把节点进行强转
  36. struct StackNode *node = (struct StackNode *)data;
  37. node->next = ls->header.next;
  38. ls->header.next = node;
  39. ++(ls->size);
  40. }
  41. // 出栈
  42. void PopLinkStack(LinkStack stack)
  43. {
  44. if (NULL == stack)
  45. {
  46. return;
  47. }
  48. struct LStack *ls = (struct LStack *)stack;
  49. if (ls->size == 0)
  50. {
  51. return;
  52. }
  53. // 缓存第一个节点
  54. struct StackNode *pFirst = ls->header.next;
  55. ls->header.next = pFirst->next;
  56. ls->size--;
  57. }
  58. // 获得栈顶元素
  59. void* TopLinkStack(LinkStack stack)
  60. {
  61. if (NULL == stack)
  62. {
  63. return NULL;
  64. }
  65. struct LStack *ls = (struct LStack *)stack;
  66. if (ls->size == 0)
  67. {
  68. return NULL;
  69. }
  70. return ls->header.next;
  71. }
  72. // 获得大小
  73. int SizeLinkStack(LinkStack stack)
  74. {
  75. if (NULL == stack)
  76. {
  77. return -1;
  78. }
  79. struct LStack *ls = (struct LStack *)stack;
  80. return ls->size;
  81. }
  82. // 销毁栈
  83. void DestroyLinkStack(LinkStack stack)
  84. {
  85. if (NULL != stack)
  86. {
  87. free(stack);
  88. }
  89. stack = NULL;
  90. return;
  91. }

在主函数中使用也很容易,首先同样定义一个Student结构体,然后通过InitLinkStack函数初始化一个链表栈,接着调用PushLinkStack函数向该栈中插入数据,最后通过循环的方式输出该栈中的元素,当输出结束后调用DestroyLinkStack函数对栈进行销毁释放内存。

  1. #include "linkstack.h"
  2. struct Student
  3. {
  4. int uid;
  5. char name[64];
  6. };
  7. int main(int argc, char *argv[])
  8. {
  9. // 初始化栈,默认分配空间为1024
  10. LinkStack stack = InitLinkStack();
  11. // 穿件一些测试数据
  12. struct Student stu1 = { 1001, "admin" };
  13. struct Student stu2 = { 1002, "guest" };
  14. struct Student stu3 = { 1003, "lyshark" };
  15. // 将输入加入到栈中
  16. PushLinkStack(stack, &stu1);
  17. PushLinkStack(stack, &stu2);
  18. PushLinkStack(stack, &stu3);
  19. // 循环输出栈顶元素
  20. while (SizeLinkStack(stack) > 0)
  21. {
  22. // 获得栈顶元素
  23. struct Student *ptr = (struct Student *)TopLinkStack(stack);
  24. printf("Uid: %d --> Name: %s \n", ptr->uid, ptr->name);
  25. printf("当前栈大小: %d \n", SizeLinkStack(stack));
  26. PopLinkStack(stack);
  27. }
  28. // 销毁栈
  29. DestroyLinkStack(stack);
  30. stack = NULL;
  31. system("pause");
  32. return 0;
  33. }

7.4 C/C++ 实现链表栈的更多相关文章

  1. C语言 复杂的栈(链表栈)

    //复杂的栈--链表栈 #include<stdio.h> #include<stdlib.h> #define datatype int//定义链表栈数据类型 //定义链表栈 ...

  2. java——链表、链表栈 LinkedListStack、链表队列 LinkedListQueue

    LikedList: package Date_pacage; public class LinkedList<E> { public static void main(String[] ...

  3. Python与数据结构[1] -> 栈/Stack[0] -> 链表栈与数组栈的 Python 实现

    栈 / Stack 目录 链表栈 数组栈 栈是一种基本的线性数据结构(先入后出FILO),在 C 语言中有链表和数组两种实现方式,下面用 Python 对这两种栈进行实现. 1 链表栈 链表栈是以单链 ...

  4. 12.java链表栈和数组栈

    栈是一个先入后出的有序列表,栈是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表,一端为变化的一端,称为栈顶,另一端是固定的,称为栈底.先入的元素在栈底,最后放入的元素在栈顶,删除 ...

  5. bzoj 1098 办公楼biu —— 链表+栈

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1098 首先,没有连边的人一定得在一个连通块里: 先把所有人连成一个链表,然后从第一个人开始, ...

  6. 链表栈C语言实现

    #ifndef LINKSTACK_H_INCLUDED #define LINKSTACK_H_INCLUDED #include <stdlib.h> #include <std ...

  7. 链表栈的C语言实现

    #ifndef _CONST_H_#define _CONST_H_ #include <stdio.h>#include <stdlib.h> typedef enum { ...

  8. liststack——链表栈(procedure)

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include "list.h&q ...

  9. 剑指offer-反向遍历链表-栈和递归2种方法(一次性跑通)

  10. 二叉树、栈、队列、链表的Java代码实现

    这是我的学习总结. 如有文章存在谬误,欢迎指出,有其他意见或者建议,也欢迎留言 二叉树链表 前序遍历:先访问根节点,然后访问左子树.右子树 中序遍历:先访问左子树,然后访问根节点.右子树 后序遍历:先 ...

随机推荐

  1. 记一次go应用在k8s pod已用内存告警不准确分析

    版权说明: 本文章版权归本人及博客园共同所有,转载请在文章前标明原文出处( https://www.cnblogs.com/mikevictor07/p/17968696.html ),以下内容为个人 ...

  2. SE11/SE16N修改表数据

    1.SE11修改方法 首先修改显示格式 选择SE16标准列表 双击这条数据 输入/H,回车,再回车 修改CODE为EDIT,F8 此时,数据已经可以修改了 2.SE16N修改方法 2.1断点修改 输入 ...

  3. LLVM 参考链接

    https://www.llvm.org/ LLVM Essentials(Paperback) LLVM 编译器 https://www.cs.cmu.edu/afs/cs.cmu.edu/acad ...

  4. 0x03~04 前缀和与差分、二分

    A题:HNOI2003]激光炸弹 按照蓝书上的教程做即可,注意这道题卡空间用int 而不是 long long. int g[5010][5010]; int main() { ios_base::s ...

  5. Python pydot与graphviz库在Anaconda环境的配置

      本文介绍在Anaconda环境中,安装Python语言pydot与graphviz两个模块的方法.   最近进行随机森林(RF)的树的可视化操作,需要用到pydot与graphviz模块:因此记录 ...

  6. 动态给div赋值高,使页面高度100%

    import { ref, onMounted, onUnmounted, computed, nextTick } from 'vue' const boxRef = ref() const sea ...

  7. Python异步编程原理篇之协程的IO

    协程的IO asyncio 作为实现异步编程的库,任务执行中遇到系统IO的时能够自动切换到其他任务.协程使用的IO模型是IO多路复用.在 asyncio 低阶API 一篇中提到过 "以Lin ...

  8. nginx.conf 配置解析及常用配置

    本文为博主原创,未经允许不得转载: nginx.conf 配置文件配置解析 #定义 Nginx 运行的用户和用户组.默认nginx的安装用户为 nobody user www www: #启动进程,通 ...

  9. VSCODE中GIT配置

    1.问题:无法正常提交 问题描述 *使用vscode提交就会一直卡住**. 参考方案链接:VS CODE GIT 500 问题处理-pudn.com 根据这位博主的描述,应当是设置的这里选择的默认选项 ...

  10. MoeCTF 2023(西电CTF新生赛)WP

    个人排名 签到 hello CTFer 1.题目描述: [非西电] 同学注意: 欢迎你来到MoeCTF 2023,祝你玩的开心! 请收下我们送给你的第一份礼物: https://cyberchef.o ...