赞
踩
1️⃣:初始化空队列,q -> front = q -> rear = 0
2️⃣:入队a1、a2、a3,q -> front = 0, q -> rear = 3
3️⃣:出队a1、a2,q -> front = 2, q -> rear = 3
4️⃣:入队a4、a5、a6,q -> front = 2, q -> rear = 6
执行 4️⃣ 操作后队列的"尾指针"已经超出对队列的最大范围了,之后无法再进行入队操作,而队列实际空间并未占满,就造成了假溢出。
1、将队中元素依次向队头方向移动。
2、将队列空间设想成一个循环的表,即分配给队列的 m
个存储单元可以循环使用,当 rear
为 MAXSIZE
时,若队列的开始端空着,又可从头使用空着的空间。当 front
为 MAXSIZE
时也是一样。
我们采用第2种方法
5️⃣:入队a7,q -> front = 2, q -> rear = 0
base[0] 接在 base[MAXSIZE -1] 之后,若 rear + 1 == M,则令 rear = 0
实现方法: 利用 模(mod,C语言中: %)运算。
插入元素:
// 队尾入队
q -> base[q -> rear] = data;
// 更新队尾指针
q -> rear = (q -> rear + 1) % MAXSIZE;
删除元素:
// 队头元素出队
data = q -> base[q -> front];
// 更新队头指针
q -> front = (q -> front + 1) % MAXSIZE;
解决方案:
1.另外设一个标致以区别队空、队满
2.另设一个变量,记录元素个数
3.少用一个元素空间
本文实现的方法就是第三种。
/********************* 循环队列的常规操作 **************************/
Queue InitQueue(); // 初始化循环队列
int QueueFull(); // 循环队列判满
int QueueEmpty(); // 循环队列判空
int QueueLength(); // 求循环队列长度(元素个数)
int EnQueue(); // 循环队列 入队
int DeQueue(); // 循环队列 出队
void QueueStatus(); // 打印队满、队空、队长状态
/****************************************************************/
#include "stdio.h" #include "malloc.h" #define TRUE 1 #define FALSE 0 #define MAXSIZE 10 typedef int ElemType; // 定义循环队列结构体 typedef struct Queue{ int *base; // 队列首地址 int front; // 队列头下标 int rear; // 队列尾下标 }*Queue;
/*
* 初始化循环队列
*/
Queue InitQueue(){
Queue q;
// 分配循环队列空间
q -> base = (ElemType *)malloc(sizeof(ElemType) * MAXSIZE);
q -> front = q -> rear = 0;
return q;
}
/*
* 循环队列判满
* q 循环队列
*/
int QueueFull(Queue q){
if(q == NULL){
return FALSE;
}
return (q -> rear + 1) % MAXSIZE == q -> front;
}
/*
* 循环队列判空
* q 循环队列
*/
int QueueEmpty(Queue q){
if(q == NULL){
return FALSE;
}
return q -> front == q -> rear;
}
/*
* 计算循环队列长度
* q 循环队列
*/
int QueueLength(Queue q){
if(q == NULL){
return FALSE;
}
return (q -> rear - q -> front + MAXSIZE) % MAXSIZE;
}
/*
* 循环队列 入队
* q 循环队列
* data 入队元素
*/
int EnQueue(Queue q, ElemType data){
if(QueueFull(q)){
return FALSE;
}
// 队尾入队
q -> base[q -> rear] = data;
// 更新队尾指针
q -> rear = (q -> rear + 1) % MAXSIZE;
return TRUE;
}
/*
* 循环队列 出队
* q 循环队列
* *val 用来存出队元素的数据
*/
int DeQueue(Queue q, ElemType *val){
if(QueueEmpty(q)){
return FALSE;
}
// 队头元素出队
*val = q -> base[q -> front];
// 更新队头指针
q -> front = (q -> front + 1) % MAXSIZE;
return TRUE;
}
/* * 打印队满、队空、队长状态 * q 循环队列 */ void QueueStatus(Queue q){ printf("QueueFull():%d\n", QueueFull(q)); printf("QueueEmpty():%d\n", QueueEmpty(q)); printf("QueueLength():%d\n\n", QueueLength(q)); } // 程序主入口 int main(int argc, char const *argv[]) { Queue q = InitQueue(); printf("QueueMaxSize: %d\n\n", MAXSIZE); QueueStatus(q); // 打印队满、队空、队长状态 // 入队 printf("EnQueue():"); for(int i = 1; i < MAXSIZE * 2; i+=2){ printf("%d\t", i); EnQueue(q, i); } printf("\n"); QueueStatus(q); // 出队 int val; printf("DeQueue():"); while(!QueueEmpty(q)){ DeQueue(q, &val); printf("%d\t", val); } printf("\n"); QueueStatus(q); // 测试循环队列是否会假溢出 int num = 20; printf("EnQueue(%d): %d\t(0 Failed, 1 Success)\n", num, EnQueue(q, num)); QueueStatus(q); return 0; }
结果如下:
QueueMaxSize: 10 QueueFull():0 QueueEmpty():1 QueueLength():0 EnQueue():1 3 5 7 9 11 13 15 17 19 QueueFull():1 QueueEmpty():0 QueueLength():9 DeQueue():1 3 5 7 9 11 13 15 17 QueueFull():0 QueueEmpty():1 QueueLength():0 EnQueue(20): 1(0 Failed, 1 Success) QueueFull():0 QueueEmpty():0 QueueLength():1
源代码已上传到 GitHub Data-Structure-of-C,欢迎大家下载 C语言实现数据结构
✍ 码字不易,记得点赞 声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/798861
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。