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

链式栈实现

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;

}

相关推荐
不许哈哈哈2 小时前
Python数据结构
数据结构·算法·排序算法
sin_hielo4 小时前
leetcode 2872
数据结构·算法·leetcode
AI科技星5 小时前
为什么宇宙无限大?
开发语言·数据结构·经验分享·线性代数·算法
合方圆~小文6 小时前
AI摄像头精准识别技术依赖于深度算法
数据结构·数据库·数码相机·模块测试
松涛和鸣6 小时前
16、C 语言高级指针与结构体
linux·c语言·开发语言·数据结构·git·算法
小欣加油10 小时前
leetcode 1018 可被5整除的二进制前缀
数据结构·c++·算法·leetcode·职场和发展
无敌最俊朗@10 小时前
链表-力扣hot100-随机链表的复制138
数据结构·leetcode·链表
玖剹11 小时前
递归练习题(四)
c语言·数据结构·c++·算法·leetcode·深度优先·深度优先遍历
Mz122111 小时前
day04 小美的区间删除
数据结构·算法
希望有朝一日能如愿以偿14 小时前
力扣每日一题:能被k整除的最小整数
数据结构·算法·leetcode