数据结构中的队列

1.队列的定义
队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。队列是一种先进先出的线性表。允许插入的一端称为队尾,允许删除的一端称为队头。

2.队列的抽象数据类型
关于队列的操作有:
(1) InitQueue(*Q):初始化操作,建立一个共队列Q
(2) QueueEmpty(*Q):判断队列是否为空
(3) EnQueue(*Q,e):插入新元素到队列中并成为队尾元素
(4) QueueLength(Q):返回队列的个数
(5) GetHead(Q,*e):获取队列队头元素
(6) DeQueue(*Q,*e):删除队列中的队头元素
(7) ClearQueue(*Q):清空队列
(8) DestroyQueue(*Q):若队列存在,则销毁它

3.顺序队列中的溢出现象:
(1) "下溢"现象:当队列为空时,做出队运算产生的溢出现象。“下溢”是正常现象,常用作程序控制转移的条件。
(2)"真上溢"现象:当队列满时,做进栈运算产生空间溢出的现象。“真上溢”是一种出错状态,应设法避免。
(3)"假上溢"现象:由于入队和出队操作中,头尾指针只增加不减小,致使被删元素的空间永远无法重新利用。当队列中实际的元素个数远远小于向量空间的规模时,也可能由于尾指针已超越向量空间的上界而不能做入队操作。该现象称为"假上溢"现象。

4.循环队列定义
解决假溢出的办法是后面的满了,就再从头开始,也就是头尾相接的循环。我们把队列的这种头尾相接的顺序存储结构称为循环队列。

5.队列长度计算公式
引入两个指针,front指针指向队头元素,rear指针指向队尾元素的下一个位置。队列的最大尺寸为QueueSize,队列满的条件是(rear+1)%QueueSize == front。通用的计算队列长度的公式为:(rear-front+QueueSize)%QueueSize。


6.循环队列的初始化代码
Status InitQueue(SqQueue *Q)
{
Q -> front = 0;
Q -> rear = 0;
return OK;
}
循环队列求长度代码
int QueueLength(SqQueue Q)
{
return ( Q.rear - Q.front + MAXSIZE) % MAXSIZE;
}
 

7.循环队列的入队操作代码
Status EnQueue (SqQueue * Q, QElemType e)
{
if ( ( Q -> rear + 1) % MAXSIZE == Q -> front) //队列满的判断
return ERROR;
Q -> data[Q -> rear] = e;
Q -> rear = (Q -> rear +1) %MAXSIZE;  //rear指针向后移一位
return OK;
}
 

8.循环队列出队操作代码:
Status DeQueue( SqQueue *Q, QElemType *e)
{
if( Q -> front == Q -> rear) //队列空的判断
return ERROR; 
*e = Q -> data[Q -> front];
Q -> front = (Q -> front + 1) % MAXSIZE;
return OK;
}


9.队列的链式存储结构定义
队列的链式存储结构,就是线性表的单链表,不过它只能尾进头出,简称为链队列。为了方便操作,我们将队头指针指向链队列的头结点,而队尾指针指向终端结点。


10. 循环队列和链队列的比较
从时间上,它们的基本操作都是常数时间O(1),不过循环队列是事先申请好空间,使用期间不释放;对于链队列来说,每次申请和释放结点也会存在一些时间开销,如果入队出队频繁,则两者还是有细微差异。队于空间上来说,循环队列必须有一个固定的长度,所以就有了存储元素个数和空间的浪费。链队列则不存在这个问题,尽管它需要一个指针域,会产生一些空间上的开销,但可以接受。所以在空间上,链队列更加灵活。
总的来说,在可以确定队列最大值的情况下,建议用循环队列,如果无法预估队列的长度时,则用链队列。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值