队列

1.队列的基本定义

 队列 (Queue) :也是运算受限的线性表。是一种先进先出 (First In First Out ,简称 FIFO) 的线性表。只允许在表的一端进行插入,而在另一端进行删除。 
队首 (front) :允许进行删除的一端称为队首。 
队尾 (rear) :允许进行插入的一端称为队尾。

队列中没有元素时称为空队列。在空队列中依次加入元素 a 1 , a 2 , …, a n 之后, a 1 是队首元素, a n 是队尾元素。显然退出队列的次序也只能是 a 1 , a 2 , …, a n ,即队列的修改是依先进先出的原则进行的


2.队列的顺序存储结构

顺序存储结构存储的队列称为顺序队列.和顺序表一样,用一个一维数组存.对头在数组的低下标端,队尾设在高下表端.队头,队尾指针值是数组元素的下标.对头指针始终指向对头结点的前一个结点位置,初始值为0.队尾指针是指向队尾结点位置,初始值也为0.

3.队列初始条件、队列满条件、队列空条件分别是什么

队列初始条件:队头指针=队尾指针=0
队列满条件:队尾指针=m(设队列当前容量为m)
队列空条件:队头指针=队尾指针

4.顺序存储队列与站的不同之处是什么?

与栈不同的是:队列元素的出列是在队头,即下标为0的位置,意味着一个元素出队后,队列中的其他所有元素都得向前移动,以

保证队列的队头,也就是下标为0的位置不为空,该时间复杂度为O(n).

在现实中也是如此,一群人排队买票,前面的人买好了离开,后面的人就要全部向前一步,补上空位。

---- 但是为什么出队列时一定要全部移动呢?如果不去限制队列的元素必须存储在数组的前n个单元的这一条件,出队的性能就会大

大增加。也就是说,队头不需要一定在下标为0的位置

---- 为了避免当只有一个元素时,队头和队尾重合使处理变得麻烦,所以引入两个指针,front指针指向队头元素,rear指针指向队尾

元素的下一个位置,这样当front==rear时,此队列不是还剩一个元素,而是空队列。


5.当空队列时,front==rear,而当队列满时,还是front==rear,那么如何判断此时的队列究竟是空还是满呢?

办法一:设置一个标志变量flag,当front==rear且flag=0时为队列空当front==rear且flag=1时为队列满

办法二:当队列空时,条件就是front=rear,当队列满时,我们修改其条件,保留一个元素空间。也就是说,队列满时,数组中还有

一个空闲单元。队列满的条件是:(rear+1)%QueueSize==front(队列的最大尺寸是QueueSize)

---- 当rear>front时,此时队列的长度为rear-front.

---- 当rear<front时,队列的长度分为两段,一段是QueueSize-front,另一段是0+rear,总长度是:rear-front+QueueSize

因此,通用的计算队列长度公式是:(rear-front+QueueSize)% QueueSize


6.循环队列顺序存储结构用C语言如何实现?

  1. #include <iostream>  
  2. using namespace std;  
  3. #define OK 1  
  4. #define ERROR 0  
  5. #define MAXSIZE 100  
  6. typedef int Status;  
  7. typedef int QElemType;  
  8. typedef struct   
  9. {  
  10.     QElemType data[MAXSIZE];  
  11.     int front;  //头指针  
  12.     int rear;   //尾指针,若队列不空,指向队列尾元素的下一个位置  
  13. }SqQueue;  

7.队列的链存储结构是什么

链存储结构存储的队列称为链队列.队头指针指向链队列的头结点,头结点的指针域若为空,则为空队列;若不为空,则为指向队首结点的指针.
链队列设有一个队头指针,其值指向队列的头结点.也是唯一地标示一个链队.设置一个队尾指针方便插入结点.队头指针和队尾指针都是指针型变量.
链队列没有容量的限制,所以在可用的存储空间范围内,一般不会出现上溢问题,也不存在如顺序队列的假溢出问题. 


8.循环队列是如何出队与入队的?

  1. /* 若队列未满,则插入元素e为Q新的队尾元素 */  
  2. Status EnQueue(SqQueue *Q,QElemType e)  
  3. {  
  4.     if((Q->rear+1) % MAXSIZE == Q->front) //队列满的判断  
  5.         return ERROR;  
  6.     Q->data[Q->rear] = e;  
  7.     Q->rear = (Q->rear+1)%MAXSIZE;    //rear指针向后移一位置  
  8.     return OK;  
  9. }  
  10. /* 若队列不空,则删除Q中队头元素,用e返回其值 */  
  11. Status DeQueue(SqQueue *Q,QElemType *e)  
  12. {  
  13.     if(Q->front==Q->rear) //队列空的判断  
  14.         return ERROR;  
  15.     *e = Q->data[Q->front];   //将队头元素赋值给e  
  16.     Q->front = (Q->front+1)%MAXSIZE;  //front指针向后移一个位置  
  17.     return OK;  
  18. }  
9.循环队列长度是如何运算的

  1. /* 返回Q的元素个数,也就是队列的当前长度 */  
  2. int QueueLength(SqQueue& Q)  
  3. {  
  4.     return (Q.rear-Q.front+MAXSIZE) % MAXSIZE;  
  5. }  
10.循环队列有哪些优点?

循环队列的使用较为广泛,主要优点有两个:一是相较于普通数组,提供了先进先出的概念,在使用功能上进行了拓展,二是在普通队列的元素操作方式上进行了改进,增加了空间的使用效率,虽然仍然浪费了一个存储单位的空间,但是相比之前已经优化了太多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值