链栈的基本操作(链表实现)

目录

定义

我们这篇文章讲的是链栈的实现

链栈的基本操作

定义链栈

初始化栈

判断栈是否为空

入栈

出栈

获取栈顶元素

销毁栈

测试+完整代码


定义

栈(Stack)是一种遵循后进先出(LIFO,Last In First Out)原则的数据结构,即最后一个被放入栈中的元素总是第一个被拿出来。栈的基本操作包括入栈(push,将元素添加到栈顶)、出栈(pop,从栈顶移除元素)以及查看栈顶元素(peek或getTop,查看栈顶元素但不移除)。

栈的实现方式主要有两种:基于数组的栈和基于链表的栈。

  1. 基于数组的栈
    • 在基于数组的栈中,通常使用一个固定大小的数组来存储栈的元素,同时用一个变量来记录栈顶的位置。当进行入栈操作时,将元素放在数组的末尾;当进行出栈操作时,移除数组的末尾元素。如果数组已满,则栈为满栈;如果数组为空,则栈为空。
    • 基于数组的栈具有空间利用率高的优点,因为它避免了链表中的指针开销。但是,如果事先不确定栈的大小,可能需要动态地调整数组的大小,这可能会带来额外的开销。
  2. 基于链表的栈
    • 在基于链表的栈中,使用链表结构来存储栈的元素。每个链表节点包含一个数据域和一个指向下一个节点的指针。栈顶元素对应链表的头节点。入栈操作相当于在链表头部插入新节点;出栈操作则是移除链表头节点。
    • 基于链表的栈的优点是动态性强,可以根据需要动态地分配和释放内存。但是,由于每个节点都需要额外的空间来存储指针,因此空间利用率可能稍低。

除了这两种基本的实现方式外,还可以根据具体的应用场景和需求,使用其他数据结构或技术来实现栈,比如使用双向链表、静态数组等。在选择栈的实现方式时,需要权衡空间利用率、时间复杂度、动态性等因素。

我们这篇文章讲的是链栈的实现

链栈的基本操作

定义链栈

typedef struct StackNode {  int data;           // 数据域  struct StackNode *next;  // 指针域  
} StackNode, *LinkStack;

初始化栈

// 初始化栈  
void InitStack(LinkStack *s) {  *s = NULL; // 初始时栈顶指针指向NULL  
} 

判断栈是否为空

// 判断栈是否为空  
int StackEmpty(LinkStack s) {  return s == NULL;  
} 

入栈

// 入栈  
void Push(LinkStack *s, int e) {  StackNode *newNode = (StackNode *)malloc(sizeof(StackNode));  if (newNode==NULL) {perror("malloc fail;);  exit(1); // 分配内存失败  }  newNode->data = e;  newNode->next = *s; // 新节点指向当前栈顶  *s = newNode; // 更新栈顶指针  
}  

出栈

// 出栈  
int Pop(LinkStack *s) {  if (StackEmpty(*s)) {  perror("Stack empty");    return -1; // 栈空,返回错误码  }  StackNode *top = *s;  int e = top->data;  *s = top->next; // 更新栈顶指针  free(top); // 释放原栈顶节点  return e;  
}  

获取栈顶元素

// 获取栈顶元素  
int GetTop(LinkStack s) {  if (StackEmpty(s)) {  perror("Stack empty");  return -1; // 栈空,返回错误码  }  return s->data;  
} 

销毁栈

// 销毁栈  
void DestroyStack(LinkStack *s) {  StackNode *temp;  while (*s != NULL) {  temp = *s;  *s = (*s)->next;  free(temp);  }  
} 

测试+完整代码

#include <stdio.h>  
#include <stdlib.h>  typedef struct StackNode {  int data;           // 数据域  struct StackNode *next;  // 指针域  
} StackNode, *LinkStack;  // 初始化栈  
void InitStack(LinkStack *s) {  *s = NULL; // 初始时栈顶指针指向NULL  
}  // 判断栈是否为空  
int StackEmpty(LinkStack s) {  return s == NULL;  
}  // 入栈  
void Push(LinkStack *s, int e) {  StackNode *newNode = (StackNode *)malloc(sizeof(StackNode));  if (!newNode) {  exit(1); // 分配内存失败  }  newNode->data = e;  newNode->next = *s; // 新节点指向当前栈顶  *s = newNode; // 更新栈顶指针  
}  // 出栈  
int Pop(LinkStack *s) {  if (StackEmpty(*s)) {  return -1; // 栈空,返回错误码  }  StackNode *top = *s;  int e = top->data;  *s = top->next; // 更新栈顶指针  free(top); // 释放原栈顶节点  return e;  
}  // 获取栈顶元素  
int GetTop(LinkStack s) {  if (StackEmpty(s)) {  return -1; // 栈空,返回错误码  }  return s->data;  
}  // 销毁栈  
void DestroyStack(LinkStack *s) {  StackNode *temp;  while (*s != NULL) {  temp = *s;  *s = (*s)->next;  free(temp);  }  
}  // 测试代码  
int main() {  LinkStack s;  InitStack(&s);  Push(&s, 1);  Push(&s, 2);  Push(&s, 3);  printf("栈顶元素:%d\n", GetTop(s));  printf("出栈元素:%d\n", Pop(&s));  printf("出栈元素:%d\n", Pop(&s));  printf("栈顶元素:%d\n", GetTop(s));  DestroyStack(&s);  return 0;  
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/4233.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开发日志(20240422):一次以为是跨域但并不是跨域的问题排查记录

1. 日志 在前后端联调的时候&#xff0c;遇到了报错&#xff0c;如下图所示&#xff08;现在再看感觉非常简单了&#xff09;&#xff0c;发现前一个请求通过了&#xff0c;但是第二个请求报错&#xff0c;然后看到 strict-origin-when-cross-origin 条件反射的认为是跨域配置…

Java web应用性能分析之【sysbench基准测试】

Java web应用性能分析之【CPU飙高分析之MySQL】-CSDN博客 Java web应用性能分析之【Linux服务器性能监控分析概叙】-CSDN博客 Java web应用性能分析概叙-CSDN博客 Java web应用性能分析之【基准测试】-CSDN博客 上面基本科普了一下基准测试&#xff0c;这里我们将从sysbench…

深入浅出 Transformer

Transformer 背后的核心概念&#xff1a;注意力机制、编码器-解码器架构、多头注意力等等。 一、理解注意力机制 注意力机制能够集中注意力在输入序列的某些部分&#xff0c;同时忽略其他部分&#xff0c;就像我们人类在理解句子时关注特定的单词或短语一样。 自注意力是种特…

眼图仪参数理解和一些测量指标

参考资料&#xff1a; https://www.eet-china.com/mp/a35960.html 一&#xff1a;关于眼图仪&#xff1a; :::warning ●如果追溯历史&#xff0c;大约47年前&#xff0c;眼图就已经开始广泛应用。在1962年-2002的40年间&#xff0c;眼图的测量方法是基于采样示波器的传统方法…

C++默认构造函数的合成

编译器只在编译期需要的时候合成默认构造函数&#xff0c;而不是在用户需要的时候 文章目录 引入编译器合成默认构造函数的四种情况情况一 类中包含带有默认构造函数的类的成员对象情况二 派生类的基类带有默认构造函数情况三 类带有一个虚函数情况四 派生自一个虚基类的类 参考…

Day53|动态规划part14: 1143.最长公共子序列、1035. 不相交的线、53. 最大子序和

1143. 最长公共子序列 这题有点像递增子序列和公共子数组的组合&#xff0c; 要求公共子序列不一定非要是连续的。 确定dp数组下标及其含义 dp[i][j]表示text1[i - 1]与text2[j - 1]结尾的最高公共子序列。 长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的…

Redis 服务等过期策略和内存淘汰策略解析

redis服务是基于内存运行的&#xff0c;所以很多数据都存放在内存中&#xff0c;但是内存又不是无限的&#xff0c;所以redis就引出了key的过期和淘汰策略。 一、Redis的过期策略&#xff1a; 我们在set key的时候&#xff0c;可以给它设置一个过期时间&#xff0c;比如expire …

【神经网络结构可视化】PlotNeuralNet的安装、测试及创建自己的神经网络结构可视化图形

文章目录 前提准备1、下载MikTeX2、下载Git bash3、下载PlotNeuralNet 进行测试1、解压PlotNeuralNet-master.zip2、打开Git bash3、 在my_project中查看生成的pdf文件 创建自己的神经网络结构可视化图形 前提准备 1、下载MikTeX 下载链接&#xff1a; MikTeX ( https://mikt…

【图解计算机网络】TCP协议三次握手与四次挥手

TCP协议三次握手与四次挥手 三次握手流程为什么是三次握手&#xff0c;而不是两次或四次四次挥手流程TIME_WAIT 为什么要等待 2MSL为什么握手是三次&#xff0c;挥手是四次&#xff1f; 三次握手流程 首先是客户端&#xff08;也就是我们的浏览器&#xff09;发送一个SYN标志位…

C++11 数据结构5 队列的概念,队列的顺序存储,实现,测试

一&#xff0c;队列的概念 队列是一种特殊的受限制的线性表。 队列&#xff08;queue&#xff09;是只允许在一端进行插入操作&#xff0c;而在另一端进行删除操作的线性表。 队列是一种先进先出的t&#xff08;First In First Out&#xff09;的线性表&#xff0c;简称FIF…

请编写函数fun,其功能是:将所有大于1小于整数m的非素数存入xx所指数组中,非素数的个数通过k传回。

本文收录于专栏:算法之翼 https://blog.csdn.net/weixin_52908342/category_10943144.html 订阅后本专栏全部文章可见。 本文含有题目的题干、解题思路、解题思路、解题代码、代码解析。本文分别包含C语言、C++、Java、Python四种语言的解法完整代码和详细的解析。 题干 请编…

NDK 基础(五)—— C++ 高级特性2

1、左值右值 在 C 中&#xff0c;左值&#xff08;lvalue&#xff09;和右值&#xff08;rvalue&#xff09;是用于描述表达式的术语&#xff0c;它们与赋值操作和内存中对象的生命周期有关。 **左值&#xff08;lvalue&#xff09;**是指可以出现在赋值操作符左侧的表达式&a…

商店数据(九)

目录 65.店铺入驻字段表 66.店铺分类表 67.店铺配置表 68.店铺快递公司关联表 69.店铺资料附加表 70.店铺入驻流程表 71.店铺运费模板表 72.消息类型表 65.店铺入驻字段表 CREATE TABLE wst_bases (id int(11) NOT NULL AUTO_INCREMENT COMMENT 自增id,flowld int(11)…

如何安全进行速卖通自养号测评操作?

对于新加入的卖家而言&#xff0c;进行销量测评显得尤为关键。速卖通平台上的新店往往难以获得活动的扶持&#xff0c;且初始流量相当有限。因此&#xff0c;开店的首要任务便是积极展开测评工作&#xff0c;努力积累初始的评论和销售记录。测评的益处颇为显著&#xff0c;它不…

SpringBoot项目启动,传参有哪些方式?

SpringBoot项目启动&#xff0c;传参有哪些方式&#xff1f; 1.Spring级别的参数 直接在启动 Spring Boot 应用的命令行中使用 -- 后跟参数名和值的方式来传递参数。 记住&#xff1a;一般是对于Spring Boot应用特有的配置参数&#xff0c;确保它们遵循Spring Boot的配置属性命…

【视频打架行为数据集】打斗场景视频数据集简要介绍

一、UBI-Fight&#xff08;异常事件检测数据集&#xff09; 介绍 UBI-Fights 数据集是一个独特的全新大型数据集&#xff0c;涉及特定的异常检测并仍然在打斗场景中提供广泛的多样性&#xff0c;该数据集包含 80 小时的视频&#xff0c;在帧级别进行了完全注释。由 1000 个视…

# 从浅入深 学习 SpringCloud 微服务架构(五)Consul(2)

从浅入深 学习 SpringCloud 微服务架构&#xff08;五&#xff09;Consul&#xff08;2&#xff09; 段子手168 一、consul 集群&#xff1a;consul 集群的基础知识 1、启动 sonsul 服务命令&#xff1a; 以开发者模式快速启动&#xff1a; consul agent -dev -client0.0.0…

13.JAVAEE之HTTP协议

HTTP 最新的版本应该是 HTTP/3.0 目前大规模使用的版本 HTTP/1.1 使用 HTTP 协议的场景 1.浏览器打开网站 (基本上) 2.手机 APP 访问对应的服务器 (大概率) 学习 HTTP 协议, 重点学习 HTTP 的报文格式 前面的 TCP/IP/UDP 和这些不同, HTTP 的报文格式,要分两个部分来看待.请求…

移动端日志采集与分析最佳实践

前言 做为一名移动端开发者&#xff0c;深刻体会日志采集对工程师来说具有重要意义&#xff0c;遇到问题除了 debug 调试就是看日志了&#xff0c;通过看日志可以帮助我们了解应用程序运行状况、优化用户体验、保障数据安全依据&#xff0c;本文将介绍日志采集的重要性、移动端…

高级防爬还得是公众号

平时一天也就1K的流量&#xff0c;最近流量暴涨&#xff0c;已经用自研的WAF防火墙阻挡了很多恶意攻击和爬虫&#xff0c;已经过滤掉很多低级攻击和爬取了。 多出的流量&#xff0c;也仅仅多了一个导航 dh.yu7s.com 用户&#xff0c;多时没有用的机器人爬虫&#xff0c;不封掉浪…