队列简称队,它也是一种操作受限的
线性表,其限制为
仅允许在表的一端进行插入,在表的另一端进行删除。
可进行插入的一端称为
队尾(Rear),可进行删除的一端称为
队头(Front)。
向队列中插入新元素称为进队,新元素进队后就成为新的队尾元素;
从队列中删除元素称为
出队,元素出队后,其后继元素成为新的队头元素。
队列的特点:
先进先出(FIFO)
队列的存储结构也分为两种,顺序队和链队
----------------------------------------------------------------------------------------------------------------------------------
顺序队中,通常让队尾指针rear指向刚进队的元素位置,让队首指针front指向刚出队的元素位置。因此,元素进队时,rear要向后移动;元素出队时,front也要向后移动。经过一系列的出队和进队操作后,两个指针最终会达到数组末端maxSize-1处。虽然队中已经没有元素,但仍然无法让元素进队,这就是“假溢出”。
为了解决这个问题,可以将数组弄成一个
环,让rear和front沿着环走,这样就不会出现两者来到数组尽头无法继续往下走的情况,这就是循环队列。
循环队列如图所示:

(1) 由空队进队两个元素,此时front指向0,rear指向2
(2) 进队4个元素,出队3个元素,此时front指向3,rear指向6
(3) 进队2个元素,出队4个元素,此时front指向7,rear指向0
要使指针沿着环走,就要使 front=(front+1)%maxSize rear=(rear+1)%maxSize (maxSize是数组长度)
例如数组长度为8,若front的初值为0,则根据这个公式,front的取值为0,1,2,3,4,5,6,7,0,1,.......即以0-7为周期的无限循环数
1) 队空:rear==front
2) 队满:(rear+1)%maxSize==front
示意图如下:

元素入队时,先移动指针,后存入元素;元素出队时,也是先移动指针再取出元素。(可以有不同的次序,我习惯于这种。)
-
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
完整代码如下(ps:代码是循环队列)
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define maxSize 100
int a[maxSize] = { 0 };
int count = 0;
int InData()
{
int i = 0;
printf("请输入入队数据,按回车键停止!\n");
while (1)
{
scanf_s("%d", &a[i]);
i++;
count++;
char c = getchar();
if (c == '\n')
break;
}
return count;
}
/**************顺序队定义*************/
typedef struct
{
int data[maxSize];
int front; //队首指针
int rear; //队尾指针
}SqQueue;
SqQueue qu;
/*********************初始化队*****************/
void initQueue()
{
qu.front = qu.rear = 0;
}
/********************判断队空****************/
int isEmpty()
{
if (qu.front == qu.rear)
return 1; //不论队首和队尾指针指向数组中哪个位置,只要两者重合,即为队空
else
return 0;
}
/**********************入队,循环队列*********************/
void enQueue()
{
if ((qu.rear + 1) % maxSize == qu.front) //判断是否队满
return 0;
printf("入队数据顺序为:");
for (int i = 0; i < count; i++) //入队先移动队尾指针
{
qu.rear = (qu.rear + 1) % maxSize; //若队未满,则先移动指针
qu.data[qu.rear] = a[i];
printf("%d ", qu.data[qu.rear]);
}
return qu.rear;
}
int b[maxSize] = { 0 }; //存放出队的数据的
/**************************出队,循环队列*********************/
int deQueue()
{
if (qu.front == qu.rear)//若队空,则不能出队
return 0;
printf("\n出队数据顺序为:");
for (int i = 0; i < count; i++)
{
qu.front = (qu.front + 1) % maxSize;
b[i] = qu.data[qu.front];
printf("%d ", b[i]);
}
return qu.front;
}
void main()
{
InData();
initQueue();
isEmpty();
enQueue();
deQueue();
system("pause");
}