1、什么是队列
队列是一种先进先出的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。
2、什么叫假溢出
假设数组的长度是5,入队a1、a2、a3、a4,front指针指向下标为0位置,rear指针指向下标为4位置。出队
a1、a2,则front指针指向下标为2的位置,rear不变,再入队a5,此时front指针不变,rear指针移到数组之外。
数组末尾元素已经占用,再向后加,就会产生数组越界的错误,可实际上,我们的队列在下标为0和1的地方还是
空闲的。我们把这种现象叫做“假溢出”。
3、什么叫循环队列
解决假溢出的办法就是后面满了,就在从头开始,也就是头尾详解的循环。我们把队列的这种头尾详解的顺序存储结构
称为循环队列。
4、空队列时,front等于rear,现在当队列满时,也是front等于rear,那么如何判断此时队列究竟是空还是满?
办法一是设置一个编制变量flag,当front==rear,且flag=0时队列为空,当front==rear,且flag=1时队列为满。
方法二是党队列空时,条件就是front=rear,当队列满时,我们修改其条件,保留一个元素空间。也就是说,队列满时,
数组还有一个空闲单元。若队列的最大尺寸为QueueSize,那么队列满的条件是(rear+1)%QueueSize==front
(取模“%”的目的就是为了整合热啊与front大小为一个问题)。
5、计算队列长度的公式
通用的计算队列长度的公式为:(rear-front+QueueSize)%QueueSize
6、什么是队列的链式存储结构
队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而异,我们把它简称为链队列。
7、链队列的结构
typrdef int QElemType; /*QElemType类型根据世界情况而定们这里假设为int*/
typedef struct QNode /*结点结构*/
{
QElemType data;
struct QNode *next;
} QNode, *QueuePtr;
typedef struct /*队列的链表结构*/
{
QueuePtr front,rear; /*队头、队尾指针*/
}LinkQueue;
8、循环队列和链队列的比较
从时间上,它们的基本操作都是常数时间,即都为0(1)的,不过循环队列是事先申请空间,使用期间
不释放,而对于链队列,每次申请和释放结点也会存在一些时间开销,如果入队出队频繁,则两者还是鼬细微差异。
对于空间上来说,循环队列必须有一个固定的长度,所以就有了存储元素个数和空间浪费的问题。而链队列不存在
这个问题,尽管它需要一个指针域,会产生一些空间上的开销,但也可以接受。所以在空间上,链队列更加灵活。
总的来说,在可以确定队列最大值的情况下,建议用循环队列,如果无法预估队列的长度时,则用链队列。
9、循环队列的入队操作
/*若队列未满,则插入元素e为Q新的队尾元素*/
Status EnQueue(sqQueue *Q, QWlemType e)
{
if((Q->rear+1)%MAXSIZE == Q->front) /*队列的判断*/
return ERROR;
Q->data[Q->rear]=e; /*将元素e赋值给队尾*/
Q->data[Q->rear]%MAXSIZE; /*rear指针向后移一位置*/
/*若到最后刚好转到数组头部*/
return OK;
}
10、链队列的入队操作
/*插入元素e为Q的新的队尾元素*/
Status EnQueue(LinkQueue *Q, QElemType e)
{
QueuePtr s=(QueuePtr)malloc(sizeof(QNode));
if(!s) /**存储分配失败/
exit(OVERFLOW);
s->data=e;
s->next=NULL;
Q->rear->next=s; /*把拥有元素e新结点s赋值给原队尾结点的后继*/
}