数据结构循环队列
前言
循环队列可能有点难理解,可以去看看别人写的文章,我这里主要还是提供我的源码,附上一些图
一、循环队列的结构和初始化
typedef struct Queue { //队列结构
int front; //前节点
int rear; //后节点
int data[MAXSIZE]; //data存储
}Queue;
Queue* initQueue(){ /*初始化队列*/
Queue* Q = (Queue*)malloc(sizeof(Queue)); //分配Q
Q->front = Q->rear = 0; //初始化的front和rear都为0,即代表为该队列为空
return Q;
}
右图就是初始化好的样子,左图是插入了四个数据的样子
二、循环队列操作
1.判断是否队空、判断是否队满
- 队空操作
代码如下(示例):
int isEmpt(Queue* Q) //判断是否为空
{ //
if (Q->front == Q->rear) //当前节点和后节点相等即为空;
{
return 1;
}
else
{
return 0;
}
}
- 队满操作
int isFull(Queue* Q) //判断队列是否为满
{
if ((Q->rear + 1) % MAXSIZE == Q->front) //比如现在MAXSIZE为5,并且Q保存了四个数据
{ /*此时的rear的值为5,(rear+1)%5等价于(5+1)%5=1*/
return 1; /*也就是说现在的队列满了,这里是需要牺牲空间的*/
}
else
{
return 0;
}
}
2.入队
代码如下(示例):
int enQueue(Queue* Q, int data) //入队
{
if (isFull(Q)) //先判断是否为满,这里限制队列是否超了,限制在MAXSIZE-1
{
return -1;
}
else
{
Q->data[Q->rear] = data; //Q中data的数据域中第rear点继承data
Q->rear = (Q->rear + 1) % 5; //rear++;保证rear不为0
return 1;
}
}
将新元素添加到 rear 指向的空闲空间;
rear 向后移动一位,指向下一个空闲空间,为下次入队新元素做准备。
3.出队操作
代码如下(示例):
int deQueue(Queue* Q) //出队
{
int data; //定义data用于接收
if (isEmpt(Q)) //先判断是否为空
{
return -1;
}
else
{
data = Q->data[Q->rear]; //data等于Q的data域的尾部
Q->front = (Q->front + 1) % MAXSIZE; //对Q的front的头来进行++
return data;
}
}
4.遍历循环队列
代码如下(示例):
void printQueue(Queue* Q)
{
int Length = (Q->rear - Q->front + MAXSIZE) % MAXSIZE; //取得data数据域的长度
int index = Q->front; //记录索引值
for (int i = 0; i < Length; i++) //
{
printf("%d->", Q->data[index]); //
index = (index + 1) % MAXSIZE; //index++
}
printf("\n");
}
5.测试代码
代码如下(示例):
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 5 //最大长度
typedef struct Queue { //队列结构
int front; //前节点
int rear; //后节点
int data[MAXSIZE]; //data存储
}Queue;
Queue* initQueue(){ /*初始化队列*/
Queue* Q = (Queue*)malloc(sizeof(Queue)); //分配Q
Q->front = Q->rear = 0; //初始化的front和rear都为0,即代表为该队列为空
return Q;
}
int isFull(Queue* Q) //判断队列是否为满
{
if ((Q->rear + 1) % MAXSIZE == Q->front) //比如现在MAXSIZE为5,并且Q保存了四个数据
{ /*此时的rear的值为5,(rear+1)%5等价于(5+1)%5=1*/
return 1; /*也就是说现在的队列满了,这里是需要牺牲空间的*/
}
else
{
return 0;
}
}
int isEmpt(Queue* Q) //判断是否为空
{ //
if (Q->front == Q->rear) //当前节点和后节点相等即为空;
{
return 1;
}
else
{
return 0;
}
}
int enQueue(Queue* Q, int data) //入队
{
if (isFull(Q)) //先判断是否为满,这里限制队列是否超了,限制在MAXSIZE-1
{
return -1;
}
else
{
Q->data[Q->rear] = data; //Q中data的数据域中第rear点继承data
Q->rear = (Q->rear + 1) % 5; //rear++;保证rear不为0
return 1;
}
}
void printQueue(Queue* Q)
{
int Length = (Q->rear - Q->front + MAXSIZE) % MAXSIZE; //取得data数据域的长度
int index = Q->front; //记录索引值
for (int i = 0; i < Length; i++) //
{
printf("%d->", Q->data[index]); //
index = (index + 1) % MAXSIZE; //index++
}
printf("\n");
}
int deQueue(Queue* Q) //出队
{
int data; //定义data用于接收
if (isEmpt(Q)) //先判断是否为空
{
return -1;
}
else
{
data = Q->data[Q->rear]; //data等于Q的data域的尾部
Q->front = (Q->front + 1) % MAXSIZE; //对Q的front的头来进行++
return data;
}
}
void main(void)
{
int flag = 0;
int enQueue_Flag = 0;
Queue* Q = initQueue();
enQueue_Flag = enQueue(Q, 1);
enQueue_Flag = enQueue(Q, 2);
enQueue_Flag = enQueue(Q, 3);
enQueue_Flag = enQueue(Q, 4);
enQueue_Flag = enQueue(Q, 5);
if (enQueue_Flag == -1)
{
printf("入队失败\r\n");
}
printQueue(Q);
printf("%d",Q->front);
printf("%d", Q->rear);
}
总结
主要还是提供代码,其他的讲解,各位可以去参考其他大佬的文章,上述有错误的东西,麻烦指出谢谢。