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

链式栈实现

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;

}

相关推荐
Fency咖啡3 小时前
《代码整洁之道》第9章 单元测试 - 笔记
数据结构·b树
2501_906314323 小时前
优化无头浏览器流量:使用Puppeteer进行高效数据抓取的成本降低策略
开发语言·数据结构·数据仓库
C182981825753 小时前
项目中数据结构为什么用数组,不用List
数据结构
几点才到啊6 小时前
使用 malloc 函数模拟开辟一个 3x5 的整型二维数组
数据结构·算法
<但凡.9 小时前
C++修炼:list模拟实现
开发语言·数据结构·c++
敲代码的瓦龙10 小时前
C++?动态内存管理!!!
c语言·开发语言·数据结构·c++·后端
Ronin30510 小时前
【C++】13.list的模拟实现
开发语言·数据结构·c++·list
序属秋秋秋10 小时前
《数据结构初阶》【顺序表 + 单链表 + 双向链表】
c语言·数据结构·笔记·链表
无敌的牛11 小时前
AVL树的介绍与学习
数据结构·学习