当前位置: 首页 > news >正文

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

#### 链式栈实现

##### 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;
}

相关文章:

  • 力扣HOT100之链表:23. 合并 K 个升序链表
  • ComfyUI for Windwos与 Stable Diffusion WebUI 模型共享修复
  • JavaScript 中 undefined 和 not defined 的区别
  • 【深度学习】多头注意力机制的实现|pytorch
  • 生物医学AI的特种算力需求:冷冻电镜数据处理中的GPU加速方案
  • GIS开发笔记(16)解决基于osg和osgearth三维地图上添加placeNode图标点击不易拾取的问题
  • UML 活动图详解之小轿车启动活动图分析
  • Dev控件RadioGroup 如何设置一排有N个显示或分为几行
  • 在Linux中,使用IO标准库进行读写操作。
  • 塔能合作模式:解锁工厂能耗精准节能新路径
  • Flutter 泛型 泛型方法 泛型类 泛型接口
  • 《原神/星穹铁道私服怎么建?内网穿透+本地调试完整指南》
  • 游戏服务器不加防护能活多久?
  • 《明解C语言入门篇》读书笔记四
  • pytorch写张量pt文件,libtorch读张量pt文件
  • log4cpp 使用指南
  • OpenCV 图形API(66)图像结构分析和形状描述符------将一条直线拟合到三维点集上函数fitLine3D()
  • linux用户管理
  • 什么是 HENGSHI SENSE?
  • 视觉导航中的回环检测技术解析
  • 专业竞演、剧场LIVE直播,32位越剧新星逐梦上海
  • 全国电影工作会:聚焦扩大电影国际交流合作,提升全球影响力
  • 大学2025丨专访南开人工智能学院院长赵新:人工智能未来会变成通识类课程
  • 公交公司须关注新出行需求:“单车巴士”能否常态化
  • 王羲之《丧乱帖》在日本流传了1300年,将在大阪展23天
  • 从世界工厂走向全球创新中心,上海车展为何成为全球汽车行业风向标?