链式存储栈的实现如下:
1、dlinklist.h 文件
详见我的另一篇文章《线性表之双向链表实验》。
2、dlinklist.c 文件
详见我的另一篇文章《线性表之双向链表实验》。
3、linkstack.h 文件
/*
* 链式存储栈
*/
#ifndef LINKSTACK_H__
#define LINKSTACK_H__
#include "dlinklist.h"
// 给 dlinklist 起个别名
typedef dlinklist linkstack;
/*
* 初始化,创建栈
* 返回结构体类型的指针
*/
linkstack *linkstack_create(int);
/*
* 入栈
*/
int linkstack_push(linkstack *, const void *);
/*
* 出栈
*/
int linkstack_pop(linkstack *, void *);
/*
* 销毁栈
*/
void linkstack_destroy(linkstack *);
#endif
4、linkstack.c 文件
#include <stdio.h>
#include <stdlib.h>
#include "linkstack.h"
/*
* 初始化,创建栈
* 返回结构体类型的指针
*/
linkstack * linkstack_create(int initsize) {
// 使用双向链表的方式创建栈
return dlinklist_create(initsize);
}
/*
* 入栈
*/
int linkstack_push(linkstack *ptr, const void *data) {
// 使用双向链表的方式将数据入栈
return dlinklist_insert(ptr, data, DLINKLIST_FORWARD);
}
/*
* 表示永远匹配
*/
static int always_match(const void *p1, const void *p2) {
return 0;
}
/*
* 出栈
*/
int linkstack_pop(linkstack *ptr, void *data) {
/*
* 使用双向链表的方式将数据出栈
* 这里的数值(void *)0,只是随便给一个 void * 的数值
* 只是因为在双向链表的 dlinklist_fetch() 需要有这么一个参数
* 第三个参数同样是因为在双向链表的 dlinklist_fetch() 需要有这么一个参数
* 因此,提供一个永远匹配的方法 always_match()
* 这里永远只删除第一个有效结点,即实现出栈操作
*/
return dlinklist_fetch(ptr, (void *)0, always_match, data);
}
/*
* 销毁栈
*/
void linkstack_destroy(linkstack *ptr) {
dlinklist_destroy(ptr);
}
5、main.c 文件
#include <stdio.h>
#include <stdlib.h>
#include "linkstack.h"
#define NAMESIZE 32
/*
* 用户自定义的结构体
* 学生信息
*/
struct stu_st {
int id; // 学号
char name[NAMESIZE]; // 姓名
int chinese; // 语文
int math; // 数学
int english; // 英语
};
/*
* 用户自定义的数据输出函数
*/
static void display(const void *ptr) {
const struct stu_st *stu = ptr;
printf("%d %s %d %d %d\n", stu->id, stu->name, stu->chinese, stu->math, stu->english);
}
int main() {
int i; // 循环索引值
int ret; // 状态返回值
struct stu_st stuinfo_st; // 操作中的学生信息
linkstack *stack = NULL;
/* 初始化链式存储栈 */
stack = linkstack_create(sizeof(struct stu_st));
if (stack == NULL) {
fprintf(stderr, "初始化链式存储栈 stack 失败!\n");
exit(1);
}
/* 往链式存储栈中插入 7 条随机数据 */
for (i = 0; i < 7; i++) {
stuinfo_st.id = i; // 学号
snprintf(stuinfo_st.name, NAMESIZE, "stu%d", i); // 姓名
stuinfo_st.chinese = rand() % 100; // 语文
stuinfo_st.math = rand() % 100; // 数学
stuinfo_st.english = rand() % 100; // 英语
ret = linkstack_push(stack, &stuinfo_st);
if (ret != 0) {
fprintf(stderr, "数据入栈失败!\n");
exit(1);
}
}
printf("链式存储栈中的学生信息:\n");
/* 数据出栈 */
while(1) {
ret = linkstack_pop(stack, &stuinfo_st);
if (ret == -1) {
break;
}
/* 用户自定义的函数显示数据 */
display(&stuinfo_st);
}
/* 销毁链式存储栈 */
linkstack_destroy(stack);
exit(0);
}
6、Makefile 文件
CC=gcc
CFLAGS+=-c -Wall -g
linkstack:$(OBJS)
$(CC) $^ -o $@
%.o:%.c
$(CC) $^ $(CFLAGS) -o $@
clean:
$(RM) *.o linkstack -r
执行效果:
gcc main.c -c -Wall -g -o main.o
gcc linkstack.c -c -Wall -g -o linkstack.o
gcc dlinklist.c -c -Wall -g -o dlinklist.o
gcc main.o linkstack.o dlinklist.o -o linkstack
root@RicenOS:~# ./linkstack
链式存储栈中的学生信息:
6 stu6 72 36 11
5 stu5 26 40 26
4 stu4 90 59 63
3 stu3 21 62 27
2 stu2 86 92 49
1 stu1 15 93 35
0 stu0 83 86 77
Copyright © 2005-2023 by www.ricensoftwares.com.cn All Rights Reserved.