一、原理和思路
1.原理
通过引入一个size
变量来记录队列中当前元素的数量,可以非常直观地判断队列的状态:
队列为空:当
size == 0
时,队列为空。队列已满:当
size == MAX_SIZE
时,队列已满。
每次入队操作后可以进行一次size++,出队操作进行size--,从而不需要借助头指针和尾指针,就可以记录队列中元素的个数而不需要牺牲一个元素空间来判断队列是否已满。
2.思路
①设计一个队列的结构体:
队列需要一个数组来存储元素,还需要front和rear指针来表示队头和队尾的位置,以及一个size变量来记录当前队列的长度。
②判断是否为空或者已满:
直接通过size来判断队列是否为空(size == 0)或已满(size == MAX_SIZE)。
③实现入队和出队操作:
入队时👉👉
如果队列已满,提示用户无法入队;否则,将元素添加到队尾,并更新rear指针和size变量。
出队时👉👉
如果队列为空,提示用户无法出队;否则,从队头移除元素,并更新front指针和size变量。
④查找功能:
查找一个元素在队列中的位置,从队头开始遍历队列,直到找到目标元素或遍历完整个队列。如果找到,返回元素的位置(从0开始计数);如果没找到,返回-1。
⑤遍历功能:
只需要从队头开始,依次输出队列中的每个元素,直到队尾。
⑥计算长度:
已经通过size变量实现了,可以直接返回size的值。
⑦户交互部分:
提供一个菜单系统,让用户可以选择不同的操作。这个部分需要处理用户输入,并根据选择调用相应的函数。
二、分段代码解析
其实只是在牺牲一个存储单元的逻辑功能上的改善改进,大体的逻辑思路时一样的,具体可以参考文章:
用c语言实现——顺序队列支持用户输入交互、入队、出队、查找、遍历、计算队列长度等功能。确定判断判满的方法为:牺牲一个存储单元方式-CSDN博客
改进点:
①在每次入队操作后,size++
②在每次出队操作后,size--
③初始化size为0
④判断已满的操作为:size==MAX_SIZE;
⑤判断已空的操作为:size==0;
⑥计算队列长度:直接返回q->size 即size 的长度即可
三、完整代码
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_SIZE 10 // 队列的最大容量
// 定义队列结构
typedef struct {
int data[MAX_SIZE]; // 存储队列元素的数组
int front; // 队头指针
int rear; // 队尾指针
int size; // 当前队列中元素的个数
} SeqQueue;
// 初始化队列
void initQueue(SeqQueue *q) {
q->front = 0;
q->rear = 0;
q->size = 0;
}
// 判断队列是否为空
bool isEmpty(SeqQueue *q) {
return q->size == 0;
}
// 判断队列是否已满
bool isFull(SeqQueue *q) {
return q->size == MAX_SIZE;
}
// 入队操作
bool enqueue(SeqQueue *q, int value) {
if (isFull(q)) {
printf("队列已满,无法入队!\n");
return false;
}
q->data[q->rear] = value;
q->rear = (q->rear + 1) % MAX_SIZE; // 循环队列
q->size++;
return true;
}
// 出队操作
bool dequeue(SeqQueue *q, int *value) {
if (isEmpty(q)) {
printf("队列为空,无法出队!\n");
return false;
}
*value = q->data[q->front];
q->front = (q->front + 1) % MAX_SIZE; // 循环队列
q->size--;
return true;
}
// 查找元素
int find(SeqQueue *q, int value) {
if (isEmpty(q)) {
printf("队列为空,无法查找!\n");
return -1;
}
int index = -1;
int i = q->front;
int count = 0;
while (count < q->size) {
if (q->data[i] == value) {
index = count; // 返回元素在队列中的位置(从0开始)
break;
}
i = (i + 1) % MAX_SIZE;
count++;
}
return index;
}
// 遍历队列
void traverse(SeqQueue *q) {
if (isEmpty(q)) {
printf("队列为空,无法遍历!\n");
return;
}
printf("队列元素:");
int i = q->front;
for (int j = 0; j < q->size; j++) {
printf("%d ", q->data[i]);
i = (i + 1) % MAX_SIZE;
}
printf("\n");
}
// 计算队列长度
int getLength(SeqQueue *q) {
return q->size;
}
// 显示菜单
void showMenu() {
printf("\n===== 顺序队列操作菜单 =====\n");
printf("1. 入队\n");
printf("2. 出队\n");
printf("3. 查找元素\n");
printf("4. 遍历队列\n");
printf("5. 计算队列长度\n");
printf("6. 退出\n");
printf("请选择操作(1-6): ");
}
// 主函数
int main() {
SeqQueue q;
initQueue(&q);
int choice, value, index;
while (true) {
showMenu();
scanf("%d", &choice);
switch (choice) {
case 1: // 入队
printf("请输入要入队的元素: ");
scanf("%d", &value);
if (enqueue(&q, value)) {
printf("%d 入队成功!\n", value);
}
break;
case 2: // 出队
if (dequeue(&q, &value)) {
printf("%d 出队成功!\n", value);
}
break;
case 3: // 查找元素
printf("请输入要查找的元素: ");
scanf("%d", &value);
index = find(&q, value);
if (index != -1) {
printf("元素 %d 在队列中的位置是: %d\n", value, index);
} else {
printf("队列中不存在元素 %d\n", value);
}
break;
case 4: // 遍历队列
traverse(&q);
break;
case 5: // 计算队列长度
printf("当前队列长度为: %d\n", getLength(&q));
break;
case 6: // 退出
printf("程序结束!\n");
exit(0);
default:
printf("无效的选择,请重新输入!\n");
}
}
return 0;
}
以上时基于VS2022编译器用c语言实现——顺序队列。判断队列已满或者空的情况是通过增加size变量记录长度来实现。支持用户输入交互、入队、出队、查找、遍历、计算长度等功能。
❀❀❀❀❀❀❀❀❀❀