目录
一、普通的顺序存储队列
二、循环队列
(1)少用一个元素空间
i、初始化队列操作:
iii、入队操作:
iv、出队操作:
(2)设置flag标志
i、初始化队列操作:
ii、判断队空操作:
iii、入队操作:
iv、出队操作:
(3)设置length存储队列元素的个数
i、初始化队列操作:
ii、判断队空操作:
iii、入队操作:
iv、出队操作:
(4) 总结
三、循环队列测试程序
(1)少用一个元素空间
(2)设置flag标志
(3)设置length存储队列元素的个数
四、拓展
(1)思路
(2)修改代码
队空和队满条件没有改变。
i、初始化操作:
ii、判断队列为空操作:
iii、入队操作:
iv、出队操作:
(3)测试程序
一、普通的顺序存储队列
在介绍循环队列三种判断队空、队满操作之前,先解释下为啥会用循环队列。
队列:一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一段称为队尾,允许删除的一段称为队头。
咱们看一下普通的顺序存储队列:
普通的顺序储存队列的存储结构为:
#define MAXSIZE 5
typedef int DataType;
typedef struct Queue
{
DataType data[MAXSIZE]; // 存储队列的数据空间
int front; // 队头指针
int rear; // 队尾指针
}SeqQueue;
如图所示:
front、rear分别指向队头,也就是数组索引为0的地方,此时队列为空(即rear == front),
现在将0、1、2、3、4依次入队(队尾指针rear一直向后移,队头指针front不动)。
如图所示:
0、1、2、3、4入队后,rear指向数组的后面,此时队满(即rear == MAXSIZE),然后再将0、1、2、3、4出队,出队后变为 队尾指针和队头指针都指向数组后面(即 rear == front),但如果现在 5 想入队却又入不了,应为 rear的值已经超过数组的最大索引,像这种数组有位置但却无法插入的这种现象叫做“假溢出”。
如图所示:
但如果咱们想rear在数组索引为0处就好。有这个想法的同学很不错,这就引出了循环队列。
二、循环队列
像上面想的那样,咱们只要把队尾和队头连,那个rear不就指向数组索引为0的地方,这就是循环队列。而怎样实现呢?只需将 入队后的rear 和 出队后的front 同 MAXSIZE取余即可。例如上面的队满时,rear = 5,对MAXSIZE取余后,即 rear = rear % MAXSIZE = 0;符合我们的想法。
rear = (rear + 1) % MAXSIZE; // 入队后取余
front = (front + 1) % MAXSIZE; // 出队后取余
循环队列:队列头尾相接的顺序存储结构就是循环队列。
如图所示:
此时循环队列为空(rear == front)。然后将0、1、2、3、4入队,此时的rear会指向数组索引为0的地方,不会像上面普通队列那样指到数组外。
然后将0、1出队,rear指针不动,front指向2处。
此时 5 入队,如果是普通队列的话,此时入队便失败(由于rear指向了数组外),但循环队列不会,此时rear指向 0 处,而之前 0 处的项已经出队,故可入队。
此时衍生一个问题,就是咱们之前队满时,有rear == front,但之前队空时 ,也有rear == front。那当 rear == front 时,是队空还是队满呢?这是不是很有歧义,所以咱们就要来解决这个问题。(即使判断队空和队满的条件不同,消除歧义)。
解决这个问题的三种方法:
- 少用一个元素的空间;
- 设置一个flag,来区别队列的 “空” 和 “满” ;
- 设置一个变量。统计队列中的元素数量。
(1)少用一个元素空间
当队满时,rear 和 front相差一个元素,此时的 rear 不等于 front,也就区分了队空和队满的条件(即 rear == front 为队空,而非队满)。
此时 (rear + 1) % MAXSIZE == front 为队队满,rear == front 为队空。
队空的判断条件:
q->rear == q->front
队满的判断条件:
(q->rear + 1) % MAXSIZE == q->front;
队列的存储结构:
#define MAXSIZE 5
typedef int DataType;
typedef struct Queue
{
DataType data[MAXSIZE]; // 存储队列的数据空间
int front; // 队头指针
int rear; // 队尾指针
}SeqQueue;
i、初始化队列操作:
利用malloc()函数分配队列的存储结构,再将 front = rear = 0;此时队列为空。
SeqQueue* InitQueue()
{
SeqQueue* q;
q = (SeqQueue*)malloc(sizeof(SeqQueue)); // 队列的存储结构
q->front = q->rear = 0; // 初始化rear和front,队列为空
printf("循环队列已经创建完毕\n");
return q;
}
ii、判断队空操作:
利用队空判断条件 rear == front;成立队列为空,不成立队列不为空。
bool QueueEmpty(SeqQueue* q)
{
if (q->rear == q->front) // 判断队空
return true;
return false;
}
iii、入队操作:
首先利用队满条件判断队列是否为满,队满则退出入队函数,不为满着进行入队操作,并将 rear 利用 rear =(rear+1) % MAXSIZE 进行更新。
bool EnQueue(SeqQueue* q, DataType x)
{
if ((q->rear+1) % MAXSIZE == q->front) // 判断队满
{
printf("循环队列已满!\n");
return false;
}
q->data[q->rear] = x; // 入队
q->rear = (q->rear + 1) % MAXSIZE; // 更新rear
return true;
}
iv、出队操作:
利用队空条件判断队列是否为空,队列为空不能进行出队操作。队不为空时,进行出队操作,并将front = (front + 1) % MAXSIZE 进行更新。
DataType DeQueue(SeqQueue* q)
{
DataType x; // 出队元素的值
if (q->rear == q->front) // 判断队空
{
printf("队列为空!不能进行删除操作\n");
return -1;
}
x = q->data[q->front]; // 出队
q->front = (q->front + 1) % MAXSIZE; // 更新front
return x;
}
(2)设置flag标志
当设置flag标志时,就不需要空出一个元素的位置。队满时,flag对应一个值,队空时,flag对应一个与队满时flag的值不同的值(即队空和队满的flag值不一样),所以当 front == rear 时,依靠 flag值就可以区分队空队满。
注:flag标志可以自选,符合上面的flag条件即可。(队满和队空的flag值不同)。
队列的存储结构:
#define MAXSIZE 5
typedef int DataType;
typedef struct Queue{
DataType data[MAXSIZE];
int front;
int rear;
bool flag;
}SeqQueue;
当 rear = front 且 flag = flase 时队空.
当 rear = front 且 flag = true时,队列为满。
队空判断条件:
(q->front == q->rear) && !(q->flag)
队满判断条件:
(q->front == q->rear) && q->flag
i、初始化队列操作:
利用malloc()函数创建队列,初始化 rear = front = 0,并将 flag 设置为队空标志(flag = false)。
SeqQueue* InitQueue()
{
SeqQueue* q;
q = (SeqQueue*)malloc(sizeof(SeqQueue)); // 分配队列的内存
q->flag = false; // 设置队空标志
q->front = q->rear = 0; // 初始化 rear和 front
printf("循环队列已经创建完毕\n");
return q;
}
ii、判断队空操作:
利用队空判断条件进行判断,成立则队空,不成立则队不为空。
bool QueueEmpty(SeqQueue* q)
{
if ((q->front == q->rear) && !(q->flag)) // 判断队空
return true;
return false;
}
iii、入队操作:
首先判断利用队满条件判断是否可以入队,可以入队,然后再进行入队操作,并更新rear,入队后,需要判断 rear 是否等于 front,(即入队后要判断队是否为满)队满设置flag为队满的的flag值。(这就是和最开始的循环队列的区别,因为最开始的循环队列,当入队后rear = front,没设置区分队空和队满的标志,在退出入队函数后,就区分不了队空、队满,此时 rear = front)。
bool EnQueue(SeqQueue* q, DataType x)
{
if ((q->front == q->rear) && q->flag) // 判断队满
{
printf("循环队列已满!\n");
return false;
}
q->data[q->rear++] = x; // 入队
q->rear %= MAXSIZE; // 更新rear
if (q->rear == q->front) // 判断入队后,队是否为满,满则设置队满标志flag
q->flag = true; // 队满
return true;
}
iv、出队操作:
首先利用队空判断条件判断队列是否为空,可以出队,再执行出队操作,并更新front,出队后,需要判断 rear 是否等于 front,(即出队后要判断队是否为空)队空设置flag为队空的的flag值。(这就是和最开始的循环队列的区别,因为最开始的循环队列,当出队后rear = front,没设置区分队空和队满的标志,在退出出队函数后,就区分不了队空、队满,此时 rear = front)。
DataType DeQueue(SeqQueue* q)
{
DataType x; // 出队的元素的值
if ((q->front == q->rear) && !(q->flag)) // 判断队空
{
printf("队列为空!不能进行删除操作\n");
return -1;
}
x = q->data[q->front++]; // 出队
q->front %= MAXSIZE; // 更新front
if (q->front == q->rear) // 判断出队后队列是否为空,设置flag标志
q->flag = false; // 队空
return x;
}
(3)设置length存储队列元素的个数
利用length来存储队列的元素个数(即队列的长度),不需要为了判断队满、队空牺牲一个元素的空间,同时利用 length 这个变量,判断队空、队满很简单,(即length = 0,队空;length = MAXSIZE,队满),不需要利用到 rear 和 front 来判断队空、队满。
队列的存储结构:
#define MAXSIZE 5
typedef int DataType;
typedef struct Queue {
DataType data[MAXSIZE];
int front;
int rear;
int length;
}SeqQueue;
当 length = 0时,队空。
当 length = MAXSIZE时,队满。
队空判断条件:
q->length == 0
队满判断条件:
q->length == MAXSIZE
i、初始化队列操作:
利用malloc()函数分配队列的空间,并初始化 rear 和 front,初始化 length = 0,为队空的标志。
SeqQueue* InitQueue()
{
SeqQueue* q;
q = (SeqQueue*)malloc(sizeof(SeqQueue)); // 分配队列空间
q->length = 0; // 初始化length,队列为空
q->rear = q->front = 0; // 初始化rear 和 front
printf("循环队列已经创建完毕\n");
return q;
}
ii、判断队空操作:
直接利用 length = 0 来判断队列是否为空。
bool QueueEmpty(SeqQueue* q)
{
if (q->length == 0) // 判断队空
return true;
return false;
}
iii、入队操作:
首先利用队满条件判断队列是否已满,未满则进行入队操作,并更新rear,队列长度加一(length++)。
bool EnQueue(SeqQueue* q, DataType x)
{
if (q->length == MAXSIZE) // 判断队满
{
printf("循环队列已满!\n");
return false;
}
q->data[q->rear++] = x; // 入队
q->rear %= MAXSIZE; // 更新rear
q->length++; // 队列长度加一
return true;
}
iv、出队操作:
利用队列为空条件判断队列是否为空,空就不进行出队操作。不为空时,出队,更新front,队列长度减一(length--)。
DataType DeQueue(SeqQueue* q)
{
DataType x; // 出队元素的值
if (q->length == 0) // 判断队空
{
printf("队列为空!不能进行删除操作\n");
return -1;
}
q->data[q->front++] = x; // 出队
q->front %= MAXSIZE; // 更新front
q->length--; // 队列的长度减一
return x;
}
(4) 总结
总体来说,使用 length 来保存队列的元素个数(队列长度)的方法,是最简单的。而带有flag标志区分队满、对空的方法,则较难点。牺牲一个元素的方法在二者之间,可以根据自身的情况来选用这三种方法的一种。
三、循环队列测试程序
在所有队列使用之前,均要初始化队列。
(1)少用一个元素空间
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#define MAXSIZE 5
typedef int DataType;
typedef struct Queue{
DataType data[MAXSIZE];
int front;
int rear;
}SeqQueue;
SeqQueue* InitQueue();
bool QueueEmpty(SeqQueue* q);
bool EnQueue(SeqQueue* q, DataType x);
DataType DeQueue(SeqQueue* q);
void ShowQueue(SeqQueue* q);
int ShowMeanu();
int main(void)
{
int choice;
SeqQueue* queue;
while (true)
{
int choice;
choice = ShowMeanu();
switch (choice)
{
case 0: exit(0);
break;
case 1: queue = InitQueue();
break;
case 2: {
int x;
printf("请输入要入队的值:");
scanf("%d", &x);
EnQueue(queue, x);
}
break;
case 3: DeQueue(queue);
break;
case 4: {
bool statue = QueueEmpty(queue);
if (statue)
printf("队列为空\n");
else
printf("队列不为空\n");
}
break;
case 5: ShowQueue(queue);
break;
default: printf("请输入恰当的测试功能!!!\n");
}
}
return 0;
}
int ShowMeanu()
{
int choice;
printf("\n欢迎来到循环队列测试程序!!!!!\n");
printf("有以下功能可提供测试\n");
printf("1.创建循环队列 2.入队\n");
printf("3.出队 4.判断队空\n");
printf("5.队列显示\n");
printf("0.退出程序\n");
printf("你需要测试的功能是:");
scanf("%d", &choice);
return choice;
}
SeqQueue* InitQueue()
{
SeqQueue* q;
q = (SeqQueue*)malloc(sizeof(SeqQueue));
q->front = q->rear = 0;
printf("循环队列已经创建完毕\n");
return q;
}
bool QueueEmpty(SeqQueue* q)
{
if (q->rear == q->front) // 判断队空
return true;
return false;
}
bool EnQueue(SeqQueue* q, DataType x)
{
if ((q->rear+1) % MAXSIZE == q->front)
{
printf("循环队列已满!\n");
return false;
}
q->data[q->rear] = x;
q->rear = (q->rear + 1) % MAXSIZE;
return true;
}
DataType DeQueue(SeqQueue* q)
{
DataType x;
if (q->rear == q->front) // 判断队空
{
printf("队列为空!不能进行删除操作\n");
return -1;
}
x = q->data[q->front];
q->front = (q->front + 1) % MAXSIZE;
return x;
}
void ShowQueue(SeqQueue* q)
{
int front, rear;
front = q->front;
rear = q->rear;
if (rear == front)
{
printf("队列为空!!!\n");
return;
}
while (rear != front)
printf("%d\n", q->data[front++]);
return;
}
(2)设置flag标志
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#define MAXSIZE 5
typedef int DataType;
typedef struct Queue{
DataType data[MAXSIZE];
int front;
int rear;
bool flag;
}SeqQueue;
SeqQueue* InitQueue();
bool QueueEmpty(SeqQueue* q);
bool EnQueue(SeqQueue* q, DataType x);
DataType DeQueue(SeqQueue* q);
void ShowQueue(SeqQueue* q);
int ShowMeanu();
int main(void)
{
int choice;
SeqQueue* queue;
while (true)
{
int choice;
choice = ShowMeanu();
switch (choice)
{
case 0: exit(0);
break;
case 1: queue = InitQueue();
break;
case 2: {
int x;
printf("请输入要入队的值:");
scanf("%d", &x);
EnQueue(queue, x);
}
break;
case 3: DeQueue(queue);
break;
case 4: {
bool statue = QueueEmpty(queue);
if (statue)
printf("队列为空\n");
else
printf("队列不为空\n");
}
break;
case 5: ShowQueue(queue);
break;
default: printf("请输入恰当的测试功能!!!\n");
}
}
return 0;
}
int ShowMeanu()
{
int choice;
printf("\n欢迎来到循环队列测试程序!!!!!\n");
printf("有以下功能可提供测试\n");
printf("1.创建循环队列 2.入队\n");
printf("3.出队 4.判断队空\n");
printf("5.队列显示\n");
printf("0.退出程序\n");
printf("你需要测试的功能是:");
scanf("%d", &choice);
return choice;
}
SeqQueue* InitQueue()
{
SeqQueue* q;
q = (SeqQueue*)malloc(sizeof(SeqQueue));
q->flag = false;
q->front = q->rear = 0;
printf("循环队列已经创建完毕\n");
return q;
}
bool QueueEmpty(SeqQueue* q)
{
if ((q->front == q->rear) && !(q->flag)) // 判断队空
return true;
return false;
}
bool EnQueue(SeqQueue* q, DataType x)
{
if ((q->front == q->rear) && q->flag)
{
printf("循环队列已满!\n");
return false;
}
q->data[q->rear] = x;
++(q->rear);
q->rear %= MAXSIZE;
if (q->rear == q->front) // 设置队列已满
q->flag = true;
return true;
}
DataType DeQueue(SeqQueue* q)
{
DataType x;
if ((q->front == q->rear) && !(q->flag)) // 判断队空
{
printf("队列为空!不能进行删除操作\n");
return -1;
}
x = q->data[q->front++];
q->front %= MAXSIZE;
if (q->front == q->rear) // 设置队列为空
q->flag = false;
return x;
}
void ShowQueue(SeqQueue* q)
{
int front, rear;
front = q->front;
rear = q->rear;
if ((front == rear) && !(q->flag))
{
printf("队列为空\n");
return;
}
/*while (front != rear) // 循环输出队列元素
{
printf("%d\n", q->data[front++]);
front %= MAXSIZE;
} // 忽略了队满 rear == front*/
// 先输出一个元素,便可解决上面此种情况
printf("%d\n", q->data[front++]);
while (front != rear) // 循环输出队列元素
{
printf("%d\n", q->data[front++]);
front %= MAXSIZE;
}
return;
}
(3)设置length存储队列元素的个数
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#define MAXSIZE 5
typedef int DataType;
typedef struct Queue {
DataType data[MAXSIZE];
int front;
int rear;
int length;
}SeqQueue;
SeqQueue* InitQueue();
bool QueueEmpty(SeqQueue* q);
bool EnQueue(SeqQueue* q, DataType x);
DataType DeQueue(SeqQueue* q);
void ShowQueue(SeqQueue* q);
int ShowMeanu();
int main(void)
{
int choice;
SeqQueue* queue;
while (true)
{
int choice;
choice = ShowMeanu();
switch (choice)
{
case 0: exit(0);
break;
case 1: queue = InitQueue();
break;
case 2: {
int x;
printf("请输入要入队的值:");
scanf("%d", &x);
EnQueue(queue, x);
}
break;
case 3: DeQueue(queue);
break;
case 4: {
bool statue = QueueEmpty(queue);
if (statue)
printf("队列为空\n");
else
printf("队列不为空\n");
}
break;
case 5: ShowQueue(queue);
break;
default: printf("请输入恰当的测试功能!!!\n");
}
}
return 0;
}
int ShowMeanu()
{
int choice;
printf("\n欢迎来到循环队列测试程序!!!!!\n");
printf("有以下功能可提供测试\n");
printf("1.创建循环队列 2.入队\n");
printf("3.出队 4.判断队空\n");
printf("5.队列显示\n");
printf("0.退出程序\n");
printf("你需要测试的功能是:");
scanf("%d", &choice);
return choice;
}
SeqQueue* InitQueue()
{
SeqQueue* q;
q = (SeqQueue*)malloc(sizeof(SeqQueue));
q->length = 0;
q->rear = q->front = 0;
printf("循环队列已经创建完毕\n");
return q;
}
bool QueueEmpty(SeqQueue* q)
{
if (q->length == 0) // 判断队空
return true;
return false;
}
bool EnQueue(SeqQueue* q, DataType x)
{
if (q->length == MAXSIZE)
{
printf("循环队列已满!\n");
return false;
}
q->data[q->rear++] = x;
q->rear %= MAXSIZE;
q->length++;
return true;
}
DataType DeQueue(SeqQueue* q)
{
DataType x;
if (q->length == 0) // 判断队空
{
printf("队列为空!不能进行删除操作\n");
return -1;
}
q->data[q->front++] = x;
q->front %= MAXSIZE;
q->length--;
return x;
}
void ShowQueue(SeqQueue* q)
{
int front = q->front;
int length = q->length; // 存储队列长度
if (length == 0)
{
printf("队列为空!!!\n");
return;
}
while (length != 0)
{
printf("%d\n", q->data[front++]);
front %= MAXSIZE;
length--;
}
return;
}
四、拓展
当上面的方法三(即利用length来保存队列的元素个数),少了一个指针,你是否还能进行入队、出队的操作。这里我用少了一个队头指针(front)来做演示。
(1)思路
少了一个front队头指针,我们的出队就变的好像不知所措,我们一般想如果它能用length 和 rear 表示该多好,而这也正是解决此题的方法,我们需要找出 rear、front 和 length 这三者之间的关系。
length 表示列表长度,那 首先猜想length = rear - front 是不是可以推出 front = rear - length 呢?看下图:
此时length = 2, rear = 4,。front = rear - length = 2好像可以,但再看下图:
此时 length = 3,rear = 0。front = rear - length = -3那就不行了,故 front rear - length。
咱们想对上面第二个图(即front = -3),rear 加上空的位置个数是不是就是front,对的,它就是front,那空的位置个数等于数组的最大元素的个数减去队列的长度(MAXSIZE - length),即 front = (rear + MAXSIZE - length). 但又看第一个图:
此时 front 好像不需要MAXSIZE就可得出(front = rear - length);那现在要解决的问题就是,要在需要MAXSIZE就要有,不需要则无,因为 MAXSIZE 对其本身求模为 0,故在把上公式对MAXSIZE求模,就相当于MAXSIZE没有,故公式改进为 front = (rear + MAXSIZE - length) % MASIZE.符合两个图,那就推出了length 、rear、front三者之间的关系(即 front = (rear + MAXSIZE - length) % MASIZE)。然后利用这个关系就可以修改之前那个源码了。
(2)修改代码
队列的存储结构:
#define MAXSIZE 5
typedef int DataType;
typedef struct Queue{
DataType data[MAXSIZE];
int rear;
int length; // 少了front指针
}SeqQueue;
队空和队满条件没有改变。
队空条件:
q->length == 0
队满条件:
q->length == MAXSIZE
i、初始化操作:
利用malloc()函数分配队列的空间,初始化length和rear。
SeqQueue* InitQueue()
{
SeqQueue* q;
q = (SeqQueue*)malloc(sizeof(SeqQueue));
q->length = 0; // 初始化length
q->rear = 0; // 初始化
printf("循环队列已经创建完毕\n");
return q;
}
ii、判断队列为空操作:
利用length == 0.
bool QueueEmpty(SeqQueue* q)
{
if (q->length == 0) // 判断队空
return true;
return false;
}
iii、入队操作:
入队操作和上面的没变——利用队满条件判断队列是否已满,未满则进行入队操作,并更新rear,队列长度加一(length++)。
bool EnQueue(SeqQueue* q, DataType x)
{
if (q->length == MAXSIZE) // 判断队满
{
printf("循环队列已满!\n");
return false;
}
q->data[q->rear++] = x; // 入队
q->rear %= MAXSIZE; // 更新rear
q->length++; // 队列长度加一
return true;
}
iv、出队操作:
出队操作改变了,这里要声明一个局部变量,充当 front 队头指针,利用关系front = (rear + MAXSIZE - length) % MASIZE求出队头的位置,再进行出队操作并更新length。
DataType DeQueue(SeqQueue* q)
{
DataType x;
int front; // 局部变量,相当于队头指针
if (q->length == 0) // 判断队空
{
printf("队列为空!不能进行删除操作\n");
return -1;
}
front = (MAXSIZE - q->length + q->rear) % MAXSIZE; // 求出队头指针位置
x = q->data[front]; // 出队
q->length--; // 队列长度减一
return x;
}
如果是去掉队尾指针rear,则利用等式 rear = (front + length) % MAXSIZE 求出rear,其等式过程是怎样形成的,与上面类似(去掉front队头指针),请自行思考。文章来源:https://www.toymoban.com/news/detail-796286.html
(3)测试程序
在使用队列之前,请对队列初始化。文章来源地址https://www.toymoban.com/news/detail-796286.html
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#define MAXSIZE 5
typedef int DataType;
typedef struct Queue{
DataType data[MAXSIZE];
int rear;
int length;
}SeqQueue;
SeqQueue* InitQueue();
bool QueueEmpty(SeqQueue* q);
bool EnQueue(SeqQueue* q, DataType x);
DataType DeQueue(SeqQueue* q);
void ShowQueue(SeqQueue* q);
int ShowMeanu();
int main(void)
{
int choice;
SeqQueue* queue;
while (true)
{
int choice;
choice = ShowMeanu();
switch (choice)
{
case 0: exit(0);
break;
case 1: queue = InitQueue();
break;
case 2: {
int x;
printf("请输入要入队的值:");
scanf("%d", &x);
EnQueue(queue, x);
}
break;
case 3: DeQueue(queue);
break;
case 4: {
bool statue = QueueEmpty(queue);
if (statue)
printf("队列为空\n");
else
printf("队列不为空\n");
}
break;
case 5: ShowQueue(queue);
break;
default: printf("请输入恰当的测试功能!!!\n");
}
}
return 0;
}
int ShowMeanu()
{
int choice;
printf("\n欢迎来到循环队列测试程序!!!!!\n");
printf("有以下功能可提供测试\n");
printf("1.创建循环队列 2.入队\n");
printf("3.出队 4.判断队空\n");
printf("5.队列显示\n");
printf("0.退出程序\n");
printf("你需要测试的功能是:");
scanf("%d", &choice);
return choice;
}
SeqQueue* InitQueue()
{
SeqQueue* q;
q = (SeqQueue*)malloc(sizeof(SeqQueue));
q->length = 0;
q->rear = 0;
printf("循环队列已经创建完毕\n");
return q;
}
bool QueueEmpty(SeqQueue* q)
{
if (q->length == 0) // 判断队空
return true;
return false;
}
bool EnQueue(SeqQueue* q, DataType x)
{
if (q->length == MAXSIZE)
{
printf("循环队列已满!\n");
return false;
}
q->data[q->rear++] = x;
q->rear %= MAXSIZE;
q->length++;
return true;
}
DataType DeQueue(SeqQueue* q)
{
DataType x;
int front;
if (q->length == 0) // 判断队空
{
printf("队列为空!不能进行删除操作\n");
return -1;
}
front = (MAXSIZE - q->length + q->rear) % MAXSIZE;
x = q->data[front];
q->length--;
return x;
}
void ShowQueue(SeqQueue* q)
{
int front;
int length = q->length; // 存储队列长度
if (length == 0)
{
printf("队列为空!!!\n");
return;
}
while (length != 0)
{
front = (MAXSIZE - length + q->rear) % MAXSIZE;
printf("%d", q->data[front]);
length--;
}
return;
}
到了这里,关于(图解)循环队列的三种判断队空、队满操作(附带源码和插入删除操作等一些基本操作)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!