这段代码实现了一个循环队列的基本操作,包括初始化队列、入队、出队和查看队列的第一个元素。
代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// 定义队列结构体
typedef struct {
int* queue; // 存储队列元素的数组指针
int top; // 队列头部索引(出队的位置)
int bottom; // 队列尾部索引(入队的位置)
int queuenum; // 队列中元素的数量(未使用)
int queuemax; // 队列的最大长度
} stQueue;
// 初始化队列函数
void queue_init(stQueue* st, int maxlen) {
if (st->queue == NULL) {
// 为队列分配内存空间,长度为 maxlen + 1
st->queue = (int*)malloc((maxlen + 1) * sizeof(int));
st->queuemax = maxlen + 1; // 设置队列最大长度
st->bottom = 0; // 初始化队列尾部索引
st->top = 0; // 初始化队列头部索引
st->queuenum = 0; // 初始化队列元素数量(未使用)
}
}
// 入队函数
int queue_push(stQueue* st, int data) {
int ret = -1; // 默认返回 -1 表示失败
// 判断队列是否已满
if ((st->bottom + 1) % (st->queuemax) == st->top) {
printf("full\n"); // 打印队列已满
} else {
// 将数据存入队列尾部
st->queue[st->bottom] = data;
// 更新队列尾部索引,实现循环
st->bottom = (st->bottom + 1) % st->queuemax;
ret = 0; // 入队成功返回 0
}
return ret;
}
// 出队函数
int queue_pop(stQueue* st) {
int ret = -1; // 默认返回 -1 表示失败
// 判断队列是否为空
if (st->bottom == st->top) {
printf("empty\n"); // 打印队列为空
} else {
// 打印队列头部元素
printf("%d\n", st->queue[st->top]);
// 更新队列头部索引,实现循环
st->top = (st->top + 1) % st->queuemax;
ret = 0; // 出队成功返回 0
}
return ret;
}
// 查看队列头部元素函数
int queue_front(stQueue* st) {
int ret = -1; // 默认返回 -1 表示失败
// 判断队列是否为空
if (st->bottom == st->top) {
printf("empty\n"); // 打印队列为空
} else {
// 打印队列头部元素
printf("%d\n", st->queue[st->top]);
ret = 0; // 查看成功返回 0
}
return ret;
}
// 主函数
int main() {
char op[100] = {0}; // 操作命令缓冲区
unsigned int n, q = 0; // 队列长度和操作数量
stQueue stMyqueue = {0}; // 初始化队列结构体
scanf("%d %d", &n, &q); // 输入队列长度 n 和操作数量 q
queue_init(&stMyqueue, n); // 初始化队列
for (unsigned int i = 0; i <= q; i++) {
fgets(op, sizeof(op), stdin); // 读取操作命令
if (strstr(op, "push")) {
// 如果命令是 push,调用入队函数
queue_push(&stMyqueue, atoi(op + 5));
} else if (strstr(op, "pop")) {
// 如果命令是 pop,调用出队函数
queue_pop(&stMyqueue);
} else if (strstr(op, "front")) {
// 如果命令是 front,调用查看函数
queue_front(&stMyqueue);
}
}
return 0;
}
1. 数据结构定义
typedef struct {
int* queue; // 存储队列元素的数组指针
int top; // 队列头部(出队的位置)
int bottom; // 队列尾部(入队的位置)
int queuenum; // 当前队列中的元素数量(代码中未使用)
int queuemax; // 队列的最大长度
} stQueue;
stQueue
是一个结构体,定义了一个队列的基本属性:queue
: 用于存储队列元素的动态数组。top
: 队列的头部索引,用于出队操作。bottom
: 队列的尾部索引,用于入队操作。queuenum
: 队列中元素的数量(但在代码中没有实际使用这个字段)。queuemax
: 队列的最大长度。
2. 队列初始化函数
void queue_init(stQueue* st, int maxlen) {
if (st->queue == NULL) {
st->queue = (int*)malloc((maxlen + 1) * sizeof(int));
st->queuemax = maxlen + 1;
st->bottom = 0;
st->top = 0;
st->queuenum = 0;
}
}
queue_init
函数用于初始化队列:- 如果队列指针
queue
为空,分配maxlen + 1
个整数的内存空间。 - 将
queuemax
设置为maxlen + 1
,这表示队列的最大长度。 top
和bottom
都初始化为0
,表示队列为空。
- 如果队列指针
3. 入队操作
int queue_push(stQueue* st, int data) {
int ret = -1;
if ((st->bottom + 1) % (st->queuemax) == st->top) {
printf("full\n");
} else {
st->queue[st->bottom] = data;
st->bottom = (st->bottom + 1) % st->queuemax;
ret = 0;
}
return ret;
}
queue_push
函数用于将元素data
入队:- 通过检查
(st->bottom + 1) % st->queuemax == st->top
来判断队列是否已满。如果满了,打印 "full"。 - 如果队列未满,将
data
存储到queue[bottom]
,然后将bottom
的索引加一,并取模以实现循环队列。 - 如果操作成功,返回
0
;否则返回-1
。
- 通过检查
4. 出队操作
int queue_pop(stQueue* st) {
int ret = -1;
if (st->bottom == st->top) {
printf("empty\n");
} else {
printf("%d\n", st->queue[st->top]);
st->top = (st->top + 1) % st->queuemax;
ret = 0;
}
return ret;
}
queue_pop
函数用于将队列头部元素出队:- 通过检查
bottom == top
来判断队列是否为空。如果为空,打印 "empty"。 - 如果队列不为空,打印队列头部元素
queue[top]
,然后将top
的索引加一,并取模以实现循环队列。 - 如果操作成功,返回
0
;否则返回-1
。
- 通过检查
5. 查看队列头部元素
int queue_front(stQueue* st) {
int ret = -1;
if (st->bottom == st->top) {
printf("empty\n");
} else {
printf("%d\n", st->queue[st->top]);
ret = 0;
}
return ret;
}
queue_front
函数用于查看队列的头部元素:- 与
queue_pop
类似,通过检查bottom == top
来判断队列是否为空。 - 如果队列不为空,打印队列头部元素
queue[top]
,但不修改top
的值。 - 如果操作成功,返回
0
;否则返回-1
。
- 与
6. 主函数
int main() {
char op[100] = {0};
unsigned int n, q = 0;
stQueue stMyqueue = {0};
scanf("%d %d", &n, &q);
queue_init(&stMyqueue, n);
for (unsigned int i = 0; i <= q; i++) {
fgets(op, sizeof(op), stdin);
if (strstr(op, "push")) {
queue_push(&stMyqueue, atoi(op + 5));
} else if (strstr(op, "pop")) {
queue_pop(&stMyqueue);
} else if (strstr(op, "front")) {
queue_front(&stMyqueue);
}
}
return 0;
}
main
函数控制程序的整体流程:
- 读取两个整数
n
和q
,其中n
是队列的最大长度,q
是操作的数量。 - 初始化队列
stMyqueue
。 - 循环读取
q
次操作,根据操作类型调用相应的函数(push
、pop
或front
)。