news 2026/5/8 20:17:53

不带头节点的链式存储实现链栈

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
不带头节点的链式存储实现链栈

1.先创建一个结构体类型,有数据域和指针域

typedef struct LNode { int data; struct LNode* next; }LNode,*LinkStack;

2.以头节点为栈口进行操作进栈和出栈

头节点进栈

int HeadPush(LinkStack* Ps, int elem) { if ((*Ps) == NULL) { (*Ps) = (LNode*)malloc(sizeof(LNode)); if ((*Ps) == NULL) { return 1; } (*Ps)->data = elem; (*Ps)->next = NULL; return 0; } LNode* s = (LNode*)malloc(sizeof(LNode)); if (NULL ==s) { return 1; } s->data = elem; s->next = (*Ps); (*Ps) = s; return 0; }

头节点出栈

int HeadPop(LinkStack* Ps)//头节点出栈 { if ((*Ps) == NULL) { return 1; } LNode* p = (*Ps); (*Ps) = (*Ps)->next; free(p); return 0; } LNode* GetTail(LinkStack* Ps) { LNode* p = (*Ps); if (NULL == p) { return p; } while (p->next) { p = p->next; } return p; }

3.以尾节点为栈口进行操作进栈和出栈,因为是不带头节点的链栈,在处理尾节点的时候需要考虑到没有头节点,需要进行特殊处理

尾节点进栈

int TailPush(LinkStack*Ps,int elem) { if ((*Ps) == NULL) { (*Ps) = (LNode*)malloc(sizeof(LNode)); if ((*Ps) == NULL) { return 1; } (*Ps)->next = NULL; (*Ps)->data = elem; return 0; } LNode* p = GetTail(Ps);//得到了最后一个非空的节点 LNode* s = (LNode*)malloc(sizeof(LNode)); if (NULL == s) { return 1; } s->data = elem; s->next = p->next; p->next = s; return 0; }

尾节点出栈

int TailPop(LinkStack* Ps) { if ((*Ps) == NULL)//没有元素能够出栈 return 1; //需要找到倒数第二个非空的节点 if ((*Ps)->next == NULL) { LNode* temp = (*Ps);//只有一个元素 (*Ps) = (*Ps)->next; free(temp); return 0; } //if ((*Ps)->next->next == NULL) //{ // LNode* temp = (*Ps)->next; // (*Ps)->next = temp->next; // free(temp); // return 0; //} LNode* p = (*Ps); while (p->next->next) { p = p->next; } LNode* temp = p->next; p->next = temp->next; free(temp); return 0; }

4.打印链栈

void Display(LinkStack* Ps) { LNode* p = (*Ps); while (p) { printf("%d->", p->data); p = p->next; } printf("NULL\n"); }

5.判断一个链栈是不是空的,如果不是空的返回top元素

以头节点进行操作的top节点

void GetTop(LinkStack* Ps)//判断空栈和返回top元素 { if ((*Ps) == NULL)//说明是空表 { return 1; } return (*Ps)->data;//返回栈顶元素 }

以尾节点进行操作的top节点

LNode* GetTail(LinkStack* Ps) { LNode* p = (*Ps); if (NULL == p) { return p; } while (p->next) { p = p->next; } return p; }

6.全局代码,可以多测试几组,看是不是符合条件,主要是头节点和尾节点一定要考虑清楚

typedef struct LNode { int data; struct LNode* next; }LNode,*LinkStack; void InitStack(LinkStack* Ps) { (*Ps) = NULL;//头节点为空指针 } int HeadPush(LinkStack* Ps, int elem) { if ((*Ps) == NULL) { (*Ps) = (LNode*)malloc(sizeof(LNode)); if ((*Ps) == NULL) { return 1; } (*Ps)->data = elem; (*Ps)->next = NULL; return 0; } LNode* s = (LNode*)malloc(sizeof(LNode)); if (NULL ==s) { return 1; } s->data = elem; s->next = (*Ps); (*Ps) = s; return 0; } int HeadPop(LinkStack* Ps)//头节点出栈 { if ((*Ps) == NULL) { return 1; } LNode* p = (*Ps); (*Ps) = (*Ps)->next; free(p); return 0; } LNode* GetTail(LinkStack* Ps) { LNode* p = (*Ps); if (NULL == p) { return p; } while (p->next) { p = p->next; } return p; } int TailPush(LinkStack*Ps,int elem) { if ((*Ps) == NULL) { (*Ps) = (LNode*)malloc(sizeof(LNode)); if ((*Ps) == NULL) { return 1; } (*Ps)->next = NULL; (*Ps)->data = elem; return 0; } LNode* p = GetTail(Ps);//得到了最后一个非空的节点 LNode* s = (LNode*)malloc(sizeof(LNode)); if (NULL == s) { return 1; } s->data = elem; s->next = p->next; p->next = s; return 0; } int TailPop(LinkStack* Ps) { if ((*Ps) == NULL)//没有元素能够出栈 return 1; //需要找到倒数第二个非空的节点 if ((*Ps)->next == NULL) { LNode* temp = (*Ps);//只有一个元素 (*Ps) = (*Ps)->next; free(temp); return 0; } //if ((*Ps)->next->next == NULL) //{ // LNode* temp = (*Ps)->next; // (*Ps)->next = temp->next; // free(temp); // return 0; //} LNode* p = (*Ps); while (p->next->next) { p = p->next; } LNode* temp = p->next; p->next = temp->next; free(temp); return 0; } void Display(LinkStack* Ps) { LNode* p = (*Ps); while (p) { printf("%d->", p->data); p = p->next; } printf("NULL\n"); } void GetTop(LinkStack* Ps)//判断空栈和返回top元素 { if ((*Ps) == NULL)//说明是空表 { return 1; } return (*Ps)->data;//返回栈顶元素 } int main() { LinkStack S; InitStack(&S); //HeadPush(&S, 1); //HeadPush(&S, 2); //HeadPush(&S, 3); HeadPop(&S); TailPush(&S, 1); TailPush(&S, 2); TailPush(&S, 3); TailPush(&S, 4); TailPush(&S, 5); TailPop(&S); TailPop(&S); TailPop(&S); TailPop(&S); TailPop(&S); /*HeadPop(&S); HeadPop(&S); HeadPop(&S);*/ Display(&S); return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/2 4:09:09

台达DVPES2系列PLC与欧姆龙E5CC温控器通讯实现温控

台达DVPES2系列PLC与3台欧姆龙E5CC温控器通讯程序(TDES-7) 功能:采用台达DVPES2型号PLC,对3台欧姆龙E5CC温控器通过485方式,modbus协议,进行温度的设定,实际温度读取硬件:台达DVP24ES2系列PLC,欧…

作者头像 李华
网站建设 2026/5/8 16:03:41

Flink SQL Time Travel用 FOR SYSTEM_TIME AS OF 查询历史快照

1. Time Travel 是什么,能解决什么问题 Time Travel(时间旅行)用于查询表在某个历史时间点的“数据与表结构状态”。你可以指定一个时间点,让 Flink 返回该时间点对应的表数据,适合做: 历史对账、回溯分析…

作者头像 李华
网站建设 2026/4/24 7:01:59

36、脚本编程中的参数、循环与数据处理

脚本编程中的参数、循环与数据处理 1. 位置参数 位置参数在脚本编程中是非常重要的概念,它们允许我们在执行脚本时传递参数。以下是不同形式的位置参数及其结果: | 形式 | 结果 | | ---- | ---- | | $1 = word $2 = words $3 = with $4 = spaces | 原始位置参…

作者头像 李华
网站建设 2026/5/6 21:43:35

Arduino UNO Q 烘托圣诞节气氛

本示例将传统LED控制升级为沉浸式节日体验,基于Arduino UNO Q开发。系统包含交互式圣诞树、音乐播放器和实时视觉反馈。通过简单的网络用户界面来切换板载 LED 的状态。应用程序通过网络浏览器监听用户输入并相应地更新 LED 状态。它展示了如何在 Linux 环境中与硬件…

作者头像 李华
网站建设 2026/5/5 1:32:16

【思维模型】第一性原理 ③ ( 5 Why 分析法 | 明确问题 | 层层深入 | 验证原因 | 改进措施 )

文章目录一、5 Why 分析法1、概念简介2、核心原则3、实施步骤4、关键技巧5、常见误区6、案例分析在 【思维模型】第一性原理 ② ( 利用 “ 第一性原理 “ 进行创新 : 归零 -> 解构 -> 重构 | 跨学科学习 ) 博客中 , 屡次提到了 5 Why 分析法 , 本篇博客简…

作者头像 李华
网站建设 2026/5/7 22:41:12

AI:深度学习的前向传播和反向传播

深度学习的前向传播和反向传播是神经网络训练的核心机制,前者负责生成预测结果,后者负责根据误差优化模型参数,二者共同构成一个完整的训练迭代循环。 一、前向传播(Forward Propagation) 前向传播是神经网络从输入到输…

作者头像 李华