当前位置: 首页 > 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?
  • 视觉导航中的回环检测技术解析
  • 干细胞从科研到市场应用有多远?发展还面临何挑战?
  • 申活观察|演出场次破纪录、入境游导游档期忙,上海文旅商“热力”拉满
  • 《开始推理吧3》:演员没包袱,推理更共情
  • 辽宁男篮被横扫这一晚,中国篮球的一个时代落幕了
  • 龙翔被撤销南京市人大常委会主任职务,此前已被查
  • 《水饺皇后》领跑五一档票房,《哪吒2》上座率仍居第一