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