数据结构(七)---链式栈

#### 链式栈实现

##### linkstack.h

#ifndef _LINKSTACK_H
#define _LINKSTACK_H


// 引入相关的库文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


// 定义元素类型的别名
typedef int DATA;


//定义链式栈节点
typedef struct node
{
    DATA data;
    struct node *next;
}NODE;


//定义链式栈结构体
typedef struct 
{
    NODE *top;     //栈顶指针,其实就是链表中的头节点
    int size;     //当前元素数量
    int capacity;     //栈容量
}LinkStack;


/**
 * 初始化链式栈
 * @param s 栈结构体指针(需由调用者提前分配内存)
 * @param num 栈容量的大小
 * @return 初始化成功返回0,否则返回-1
 */
extern int lstack_init(LinkStack *s, int num);


/**
 * 判断栈是否已满
 * @param s 栈结构体指针(需由调用者提前分配内存)
 * @return 栈已满返回1
 */
extern int lstack_isfull(LinkStack *s);


/**
 * 入栈
 * @param s 栈结构体指针(需由调用者提前分配内存)
 * @param data 待入栈的数据
 * @return 成功返回0,否则返回-1
 */
extern int lstack_push(LinkStack *s, DATA data);


/**
 * 判断栈是否为空
 * @param s 栈结构体指针(需由调用者提前分配内存)
 * @return 栈为空返回1
 */
extern int lstack_isempty(LinkStack *s);


/**
 * 出栈
 * @param s 栈结构体指针(需由调用者提前分配内存)
 * @param data 接收出栈的数据指针
 * @return 成功返回0,否则返回-1
 */
extern int lstack_pop(LinkStack *s, DATA *data);


/**
 * 销毁栈
 */
extern void lstack_destroy(LinkStack *s);


#endif //_LINKSTACK_H
```

##### linkstack.c

#include "linkstack.h"


/**
 * 初始化链式栈
 * @param s 栈结构体指针(需由调用者提前分配内存)
 * @param num 栈容量的大小
 * @return 初始化成功返回0,否则返回-1
 */
int lstack_init(LinkStack *s, int num)
{
    //空指针检查
    if(!s)
    {
        perror("创建失败!");
        return -1;
    }
    
    //num的检查
    if(num <= 0)
    {
        perror("容量有误,创建失败!");
        return -1;
    }
    
    //初始化栈属性
    s->top = NULL;     //栈顶指针置空,表示空栈
    s->size = 0;     //当前元素数量为0 
    s->capacity = num;     //设置容量限制(需后续操作中校验)
    
    return 0;
}


/**
 * 判断栈是否已满
 * @param s 栈结构体指针(需由调用者提前分配内存)
 * @return 栈已满返回1
 */
int lstack_isfull(LinkStack *s)
{
    return s->size >= s->capacity;
}


/**
 * 入栈
 * @param s 栈结构体指针(需由调用者提前分配内存)
 * @param data 待入栈的数据
 * @return 成功返回0,否则返回-1
 */
int lstack_push(LinkStack *s, DATA data)
{
    //判断栈是否已满
    if(lstack_isfull(s))
    {
        perror("栈已满,数据无法入栈!");
        return -1;
    }
    
    //创建新节点
    NODE *p = (NODE*)malloc(sizeof(NODE));
    if(!p)
    {
        perror("Memory allocation failed!");
        return -1;
    }
    
    //初始化
    p->data = data;     //存储数据
    p->next = s->top;     //新节点指向原栈顶
    s->top = p;     //更新栈顶指针为新节点
    s->size++;     //元素计数增加
    
    return 0;
}


/**
 * 判断栈是否为空
 * @param s 栈结构体指针(需由调用者提前分配内存)
 * @return 栈为空返回1
 */
int lstack_isempty(LinkStack *s)
{
    if(!s)
        return 1;     //空指针视为空栈
    
    return s->size == 0;
    //return s->top = NULL;
}


/**
 * 出栈
 * @param s 栈结构体指针(需由调用者提前分配内存)
 * @param data 接收出栈的数据指针
 * @return 成功返回0,否则返回-1
 */
int lstack_pop(LinkStack *s, DATA *data)
{
    if(!s || !data)
    {
        perror("Stack is empty!");
        return -1;
    }
    
    //判断栈是否为空
    if(lstack_isempty(s))
    {
        perror("警告!试图从空栈弹出数据!");
        return -1;
    }
    
    NODE *p = s->top;     //保存栈顶节点
    *data = p->data;     //获取弹出栈的数据
    s->top = p->next;     //更新栈顶指针
    free(p);     //释放原栈顶节点
    s->size--;
    
    return 0;
}


/**
 * 销毁栈
 */
void lstack_destroy(LinkStack *s)
{
    if(!s) 
        return;     //空指针保护
    
    DATA temp;     //临时存储弹出数据
    
    //释放所有节点
    while(!lstack_isempty(s))
    {
        lstack_pop(s, &temp);     //弹出数据存入temp
    }
    return;
}
```

##### app.c

#include "linkstack.h"

int main(int argc, char const *argv[])
{
    LinkStack s;
    DATA temp;

    // 1. 初始化容量为10的链式栈
    lstack_init(&s, 10);

    // 2. 入栈测试
    printf("入栈顺序:");
    for (int i = 0; i < 10; i++)
    {
        lstack_push(&s, i + 10); // 压入10~19
        printf("%d ", i + 10);
    }
    printf("\n");

    // 测试栈满
    if (lstack_push(&s, 20) == -1)
        printf("栈已满,插入20失败\n");

    // 3. 出栈测试
    printf("出栈顺序:");
    while (!lstack_isempty(&s))
    {
        lstack_pop(&s, &temp);
        printf("%d ", temp);
    }
    printf("\n");

    // 测试栈空
    if (lstack_pop(&s, &temp) == -1)
        printf("栈已空,无法弹出\n");

    // 4. 销毁栈
    lstack_destroy(&s);
    return 0;
}

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

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

相关文章

【Spring Boot】Maven中引入 springboot 相关依赖的方式

文章目录 Maven中引入 springboot 相关依赖的方式1. 不使用版本管理&#xff08;不推荐&#xff09;2、使用版本管理&#xff08;推荐&#xff09;2.1 继承 spring-boot-starter-parent2.2 使用 spring-boot-dependencies 自定义父工程2.3引入 spring-framework-bom Maven中引…

DataStreamAPI实践原理——快速上手

引入 通过编程模型&#xff0c;我们知道Flink的编程模型提供了多层级的抽象&#xff0c;越上层的API&#xff0c;其描述性和可阅读性越强&#xff0c;越下层API&#xff0c;其灵活度高、表达力越强&#xff0c;多数时候上层API能做到的事情&#xff0c;下层API也能做到&#x…

WPF 图片文本按钮 自定义按钮

效果 上面图片,下面文本 样式 <!-- 图片文本按钮样式 --> <Style x:Key="ImageTextButtonStyle" TargetType="Button"><Setter Property="Background" Value="Transparent"/><Setter Property="BorderTh…

驱动开发硬核特训 · Day 22(上篇): 电源管理体系完整梳理:I2C、Regulator、PMIC与Power-Domain框架

&#x1f4d8; 一、电源子系统总览 在现代Linux内核中&#xff0c;电源管理不仅是系统稳定性的保障&#xff0c;也是实现高效能与低功耗运行的核心机制。 系统中涉及电源管理的关键子系统包括&#xff1a; I2C子系统&#xff1a;硬件通信基础Regulator子系统&#xff1a;电源…

设计模式全解析:23种经典设计模式及其应用

创建型模式 1. 单例模式&#xff08;Singleton Pattern&#xff09; 核心思想&#xff1a;确保一个类只有一个实例&#xff0c;并提供一个全局访问点。适用场景&#xff1a;需要共享资源的场景&#xff0c;如配置管理、日志记录等。 public class Singleton {// 静态变量保存…

力扣热题100题解(c++)—矩阵

73.矩阵置零 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 int m matrix.size(); // 行数int n matrix[0].size(); // 列数bool firstRowZero false; // 标记第一行是否包含 0bool f…

本地部署DeepSeek-R1(Dify升级最新版本、新增插件功能、过滤推理思考过程)

下载最新版本Dify Dify1.0版本之前不支持插件功能&#xff0c;先升级DIfy 下载最新版本&#xff0c;目前1.0.1 Git地址&#xff1a;https://github.com/langgenius/dify/releases/tag/1.0.1 我这里下载到老版本同一个目录并解压 拷贝老数据 需先停用老版本Dify PS D:\D…

PostSwigger Web 安全学习:CSRF漏洞3

CSRF 漏洞学习网站&#xff1a;What is CSRF (Cross-site request forgery)? Tutorial & Examples | Web Security Academy CSRF Token 基本原理 CSRF Token 是服务端生成的唯一、随机且不可预测的字符串&#xff0c;用于验证客户端合法校验。 作用&#xff1a;防止攻击…

用 Nodemon 解决 npm run serve 频繁重启服务

Nodemon 是一个基于 Node.js 构建的开发工具&#xff0c;专为帮助开发者自动监控项目文件的更改而设计。每当文件发生变更时&#xff0c;Nodemon 会自动重启 Node.js 服务器&#xff0c;无需手动停止并重启。这对于提升开发速度、减少人工操作非常有帮助&#xff0c;尤其适用于…

django admin 中更新表数据 之后再将数据返回管理界面

在Django中&#xff0c;更新数据库中的数据并将其重新显示在Django Admin界面上通常涉及到几个步骤。这里我将详细说明如何在Django Admin中更新表数据&#xff0c;并确保更新后的数据能够立即在管理界面上显示。 定义模型 首先&#xff0c;确保你的模型&#xff08;Model&…

真.从“零”搞 VSCode+STM32CubeMx+C <1>构建

目录 前言 准备工作 创建STM32CubeMx项目 VSCode导入项目&配置 构建错误调试 后记 前言 去年10月开始接触单片机&#xff0c;一直在用树莓派的Pico&#xff0c;之前一直用Micropython&#xff0c;玩的不亦乐乎&#xff0c;试错阶段优势明显&#xff0c;很快就能鼓捣一…

C语言学习之结构体

在C语言中&#xff0c;我们已经学了好几种类型的数据。比如整型int、char、short等&#xff0c;浮点型double、float等。但是这些都是基本数据类型&#xff0c;而这些数据类型应用在实际编程里显然是不够用的。比如我们没有办法用一旦数据类型来定义一个”人“的属性。因此这里…

架构-计算机系统基础

计算机系统基础 一、计算机系统组成 &#xff08;一&#xff09;计算机系统层次结构 硬件组成 主机&#xff1a;包含CPU&#xff08;运算器控制器&#xff09;、主存储器&#xff08;内存&#xff09;。外设&#xff1a;输入设备、输出设备、辅助存储器&#xff08;外存&…

【计算机网络性能优化】从基础理论到实战调优

目录 前言技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析核心概念图解核心作用讲解关键技术模块说明技术选型对比 二、实战演示环境配置要求核心代码实现案例1&#xff1a;iPerf3带宽测试案例2&#xff1a;TCP窗口优化案例3&#xff1a;QoS流量整形 运行…

Python 自动化办公:Excel 数据处理的“秘密武器”

引言 在日常的 IT 办公场景里&#xff0c;Excel 是数据处理与分析的 “常胜将军”。无论是财务人员整理账目、销售团队统计业绩&#xff0c;还是运营人员分析用户数据&#xff0c;Excel 都发挥着关键作用。但面对海量数据&#xff0c;手动操作 Excel 不仅效率低下&#xff0c;还…

缓存集群技术深度解析:从原理到实战

缓存集群技术深度解析&#xff1a;从原理到实战 一、缓存集群核心定位与架构选型 1. 集群模式核心价值 缓存集群通过数据分片、高可用保障、水平扩展解决单节点瓶颈&#xff0c;核心能力包括&#xff1a; 数据分片&#xff1a;将数据分散到多个节点&#xff0c;突破单节点内…

CSDN编辑文章时如何自动生成目录

如何自动生成目录 前置条件1. 插入目录标识符2. 编写标题层级 前置条件 需要使用markdown编辑&#xff0c;并且只有按照markdown语法编写不同的标题级别&#xff0c;才能使用这个方法自动生成对应的目录。 1. 插入目录标识符 在文章的顶部添加以下代码&#xff1a; [TOC](文…

产品经理对于电商接口的梳理||电商接口文档梳理与接入

接口梳理7个注意点总结 ①注意要测试环境和生产环境。生产上线时候要提醒研发换到生产环境调用。 ②注意必输字段和选输字段&#xff0c;要传入字段的含义和校验。枚举值不清楚含义的要询问对方含义&#xff0c;比如说单据类型字段枚举值是B2C发货单&#xff0c;BBC发货单&am…

更快的图像局部修改与可控生成:Flex.2-preview

Flex.2-preview 文本生成图像扩散模型介绍 一、模型简介 Flex.2-preview 是一种 开源的 80 亿参数文本生成图像扩散模型&#xff0c;具备通用控制和修复支持功能&#xff0c;是 Flex.1alpha 的下一代版本。该模型由社区开发并为社区服务&#xff0c;采用 Apache 2.0 许可证&a…

【Castle-X机器人】一、模块安装与调试:机器人底盘

持续更新。。。。。。。。。。。。。。。 【ROS机器人】模块安装 一、Castle-X机器人底盘1.1 结构概述1.2 驱动执行结构1.3 环境传感器1.4 电气系统1.5 Castle-x机器人底盘测试激光雷达传感器测试及数据可视化超声波传感器实时数据获取防跌落传感器测试陀螺仪测试键盘控制测试…