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

链式栈实现

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;

}

相关推荐
白狐_79811 小时前
408数据结构第5章:二叉树遍历序列题——技巧、判断与真题型总结
数据结构
Forever Nore13 小时前
学完C语言力扣第一题做不来正常吗
数据结构·算法
旖旎夜光16 小时前
LeetCode 11:盛最多水的容器(双指针问题) —— 题解
数据结构·c++·算法·leetcode·双指针
不一样的故事12618 小时前
芯片设计是一个高度复杂、分工精细的系统工程
数据结构·经验分享
梁辰兴18 小时前
软件工程:面向数据结构的设计方法
数据结构·软件工程·梁辰兴·面向数据结构的设计方法·jackson方法·warnier方法·方法比较
白狐_79819 小时前
408数据结构第7章:查找②——顺序、折半、分块查找秒杀 + 真题
数据结构·算法
hold?fish:palm20 小时前
链表的基本原理和实现(C++版本)
数据结构·c++·链表
码完就睡21 小时前
数据结构——树、二叉树基础概念
数据结构·算法
疯狂打码的少年1 天前
【数据结构】栈:定义、顺序栈与链式栈
数据结构·笔记
wabs6661 天前
关于图论【最短路径之Bellman_ford 算法|卡码网94.城市间货物运输的思考】
数据结构·算法·图论·卡码网·bellman_ford·求最短路径