牛客刷题笔记--(队列专项练习)

知识点总结

图的拓扑排序 深度优先 关键路径算法用的辅助数据结构是栈
树的层序遍历 图的广度优先遍历用的数据结构是队列
输入受限 的 双端队列 是指元素只能从 队列 的一 端输入 ,但可以从 队列 的两端 输出;
输出受限 的 双端队列 是指只有一端可以进行出队操作而从两端都可以进行入队操作的 队列。
求循环队列中的元素个数的公式为:(rear-front+size)%size,size是循环队列的容量
堆最适合创建一个优先级队列

循环队列的相关条件和公式:
1.队空条件:rear=front
2.队满条件:(rear+1) %QueueSIze=front,其中QueueSize为循环队列的最大长度
注意一下,对于普通的循环队列,当栈满或者栈空时,都有front=rear,所以,我们为了区分,约定牺牲一个元素位置,这样的话(rear+1) %QueueSIze=front就可以判断队满了(那么判断队满就不能用条件rear=front了)

题型

循环队列
判断队列元素个数
输入受限 的 双端队列 出队列顺序
输出受限 的 双端队列 出队列顺序
循环队列队空队满条件

刷题

1 循环队列的存储空间为 Q(1:100) ,初始状态为 front=rear=100 。经过一系列正常的入队与退队操作后, front=rear=99 ,则循环队列中的元素个数为(D )

1

2

99

0100

以下是循环队列的一些特性。当front=rear时,队列为空(front追到rear)或者为满(rear追到front)。

在这里插入图片描述

在循环队列中,用队尾指针 rear 指向队列中的队尾元素,用排头指针 front 指向排头元素的前一个位置。在循环队列中进行出队、入队操作时,头尾指针仍要加 1 ,朝前移动。只不过当头尾指针指向向量上界时,其加 1 操作的结果是指向向量的下界 0 。由于入队时尾指针向前追赶头指针,出队时头指针向前追赶尾指针,故队空和队满时,头尾指针均相等。故本题答案为 D 选项。

2 假设以数组A[60]存放循环队列的元素,其头指针是front=47,当前队列有50个元素,则队列的尾指针值为(B)

3

37

97

50

队列中元素的个数: (rear-front+QueueSize)%QueueSize

根据题意得:(rear - 47 + 60)% 60 = 50

=> rear = 37 选B

3 循环队列的存储空间为 Q(1:40) ,初始状态为 front=rear=40 。经过一系列正常的入队与退队操作后, front=rear=15 ,此后又退出一个元素,则循环队列中的元素个数为(A )

39,或0且产生下溢错误

14

40

15

front==rear代表着队列满,或者空。然后又退出去了一个数据,所以当为空的时候,就会产生下溢。为满的时候,就是总个数-1也就是39个

4 用链接方式存储的队列,在进行删除运算时( D )。

仅修改头指针

仅修改尾指针

头、尾指针都要修改

头、尾指针可能都要修改

在有头结点的链队列的出队操作中,一般只需修改队头指针,但当原队列中只有一个结点时,该结点既是队头也是队尾,故删去此结点时亦需修改队尾指针,使其指向头结点,且删去此结点后队列变空。

一般情况下只修改头指针,但是,当删除的是队列中最后一个元素时,队尾指针也丢失了,因此需对队尾指针重新赋值。

本题既考察了队列的先进先出的特性,又需要考虑删除时队列的不同状态。
1> 当有多于一个节点时,链表表示的队列的删除操作只需要修改头指针即可,将头指针定义为head=head.next 此时不需要修改尾指针;
2> 当队列只有一个节点时,该节点既是头又是尾,如果head==tail 则需要修改尾指针将队列置空。

5 队列{a,b,c,d,e}依次入队,允许在其两端进行入队操作,但仅允许在一端进行出队操作,则不可能得到的 出队 序 列 是(C)

b, a, c, d, e

d, b, a, c, e

d, b, c, a, e

e, c, b, a, d

题干说可以两端入队。一端出队。 a选项:b a c d e☞左入a,右入b,左入c,左入d,左入e。出队端为右端(或者整个完全相反也可以。) b选项:d b a c e☞左入a,右入b,左入c,右入d,左入e。出队端为右端(或者整个完全相反也可以。) d选项:e c b a d☞左入a,左入b,左入c,右入d,左入e。出队端为左端(或者整个完全相反也可以。)

6 STL中的优先队列是采用什么数据结构来实现的?(A)

堆

队列

栈

图

STL之优先队列
priority_queue优先队列,也就是原来我们学过的堆,按照自己定义的优先级出队时。默认情况下底层是以Vector实现的heap。
只有入队、出队、判空、大小的操作,并不具备查找功能。

STL中的priority_queue,它就是用堆实现的,插入或删除不需要排序,只是一个调整堆的过程。

7 已知输入序列为abcd经过输出受限的双向队列后能得到的输出序列有(BD)

dacb

cadb

dbca

bdac

以上答案都不对

先说结论:
对于…a…b…c…d…的输入序列(…代表其他任意元素),经过输出受限的双向队列后,
有两种类型的序列是不存在的:
…d…b…c…a…
…d…a…c…b…
也就是不能出现c夹在a和b中间的情况。

证明过程:
因为a、b、c先于 d入队且d先于a、b、c出队,所以当d出队时a、b、c还在队中。
对于a、b、c而言: a,b先入队,此时a和b的排列顺序为ab或ba,所以当c入队时,只能排在在ab或ba的两端。
即不能出现c夹在a和b中间的情况,
也就是不能出现…d…b…c…a…和…d…a…c…b…这两种情况。
证明完成。

8 最大容量为n的循环队列,队尾指针是rear,队头是front,则队满的条件是(A)。

(rear+1) MOD n==front

rear==front

rear+1==front

(rear-1) MOD n==front

9 下列叙述中正确的是(A )。

在循环队列中,队头指针和队尾指针的动态变化决定队列的长度

在循环队列中,队尾指针的动态变化决定队列的长度

在带链的队列中,队头指针与队尾指针的动态变化决定队列的长度

在循环队列中,队头指针一定小于队尾指针

【解析】在栈中,栈底保持不变,有元素入栈,栈顶指针增加;有元素出栈,栈顶指针减小。在循环队列中,队头指针和队尾指针的动态变化决定队列的长度。在循环链表中,前一个结点指向后一个结点,而最后一个结点指向头结点,只有头结点是固定的。线性链表中,由于前一个结点包含下一个结点的指针,尾结点指针为空,要插入删除元素,只需要改变相应位置的结点指针即可,头指针和尾指针无法决定链表长度。故本题答案为 A 选项。

C:链式队列,元素存储空间不一定连续,无法直接通过队头和队尾获得其长度

10 用链接方式存储的队列,在进行插入运算时 ( D ).

仅修改头指针

头、尾指针都要修改

仅修改尾指针

头、尾指针可能都要修改

一般情况下,仅需修改队尾指针;
但当队列为空时,插入元素时,队头和队尾指针都需修改

11 最大容量为n的循环队列,队尾指针是rear,队头是front,则队空的条件是(B)

(rear+1) MOD n=front

rear=front

rear+1=front

(rear-1) MOD n=front
循环队列的相关条件和公式:
1.队空条件:rear==front
2.队满条件:(rear+1) %QueueSIze==front,其中QueueSize为循环队列的最大长度
3.计算队列长度:(rear-front+QueueSize)%QueueSize
4.入队:(rear+1%QueueSize
5.出队:(front+1%QueueSize

在循环队列中,当队列为空时,有front=rear,而当所有队列空间全占满时,也有front=rear。为了区别这两种情况,规定循环队列最多只能有MaxSize-1个队列元素。

当循环队列中只剩下一个空存储单元时,队列就已经满了。因此,队列判空的条件时front=rear,而队列判满的条件时front=(rear+1)%MaxSize

在这里插入图片描述

12 在循环队列中, 若尾指针 rear 大于头指针 front, 其元素个数为 rear- front。正确

13已知循环队列存储在一维数组A[0…n-1]中,且队列非空时 front 和 rear 分别指向队头和队尾元素。若初始时队列为空,且要求第 1 个进入队列的元素存储在 A[0]处,则初始时 front和 rear 的值分别是( B)。

00

0, n-1

n-10

n-1, n-1

首先根据循环队列的公式,插入元素,front不变,rear=(rear+1)%n。在本题中,即(rear+1)%n=0,可得rear=n-1。此时队列中只有一个元素,则front与rear应该指向同一个位置,即front也应该为0。
综上,front=0, rear=n-1

14 设循环队列的容量为50(序号从0到49),现经过一系列的入队和出队运算后,有 front=16,rear=5(rear指向队尾元素的后一位置),当前循环队列中元素个数为( B)

11

39

40

12

分析:现在5-15是没有元素的,rear指向队尾元素的后一位置
求循环队列中的元素个数的公式为:(rear-front+size)%size,size是循环队列的容量

15 有一个虚拟存储系统,若进程在内存中占3页(开始时内存为空),若采用先进先出(FIFO)页面淘汰算法,当执行如下访问页号序列后1,2,3,4,5, 1,2,5,1,2,3,4,5,会发生多少缺页?(10次)

1、访问1,缺页,调入1,内存中为 1, ,;
2、访问2,缺页,调入2,内存中为 1,2,;
3、 访问3,缺页,调入3,内存中为 1,2,3;
4、 访问4,缺页,调入4,淘汰1,内存中为 4,2,3;
5、 访问5,缺页,调入5,淘汰2,内存中为 4,5,3;
6、 访问1,缺页,调入1,淘汰3,内存中为 4,5,1;
7、 访问2,缺页,调入2,淘汰4,内存中为 2,5,1;
8、 访问5,不缺页,内存中为 2,5,1;
9、 访问1,不缺页,内存中为 2,5,1;
10、 访问2,不缺页,内存中为 2,5,1;
11、访问3,缺页,调入3,淘汰5,内存中为 2,3,1;
12、访问4,缺页,调入4,淘汰1,内存中为 2,3,4;
13、访问5,缺页,调入5,淘汰2,内存中为 5,3,4;

16 在下列链队列Q中,元素a出队的操作序列为(B) (提示:p是出队操作所用的辅助节点 )
在这里插入图片描述

p=Q.front->next; p->next= Q.front->next;

p=Q.front->next; Q.front->next=p->next;

p=Q.front->next; Q.front->next=p;

p=Q.front->next; Q.front=p->next;

带头节点,所以Q.front->next指向a
先断开,再链接

17 下列叙述中正确的是(B )。

循环队列是队列的一种链式存储结构

循环队列是队列的一种顺序存储结构

循环队列是非线性结构

循环队列是一种逻辑结构

在这里插入图片描述
18 对于序列( 12 , 13 , 11 , 18 , 60 , 15 , 7 , 19 , 25 , 100 ),用筛选法建堆,必须从值为 C__ 的数据开始建初始堆

100

12

60

15

有n个元素的序列,若使用筛选法建堆,则从位置为n/2取下整的元素开始建堆 (从最后一个结点的父亲结点开始,所以是n/2)

按原顺序放到完全二叉树中,从上到下,从左到右,找到最后一个有儿子的节点开始

若元素地址从零开始,则n/2-1。若由1开始,则n/2。如果题目中未说明由零开始或是1开始,默认由零开始。

筛选建堆就是从下至上的下滤法建堆,将序列按照顺序组成一棵二叉树,从叶子节点到根节点,依次进行下滤操作;
但是很明显,叶子节点不需要下滤,所以就是从第一个非叶子节点开始。
12
13 11
18 60 15 7
19 25 100
所以其实就是从60这个节点开始了,因为加粗的几个节点都已经不用下滤了

19 有一个队列X,在X的两端都可以入队,但只允许在X的一端出队,在任意时间都可以做入队和出队操作。将序列{A,B,C,D,E}依次入队,则得到的出队序列可能有(ABD)

{B,A,C,D,E}

{D,B,A,C,E}

{D,B,C,A,E}

{E,C,B,A,D}

不管如何,B都是第二个进队的,所以出队时一定与A挨着,C在AB左右均可,以此类推。选ABD。

20 以下开源软件中经常被用作队列的是哪个?BD

MongoDB

Redis

Memcached

kafka

MongoDB 是非关系型数据库
Memcached 是分布式缓存系统

21 设指针变量fron t 表示链式队列的队头指针,指针变量rear表示链式队列的队尾指针,指针变量s指向将要入队列的结点X,则入队列的操作序列为(C)。

front->next=s;front=s;

s->next=rear;rear=s;

rear->next=s;rear=s;

s->next=front;front=s;

先让rear的下一个指向目标变为s,再把rear更新为s

22 设顺序循环队列Q[0,M-1]的头指针和尾指针分别为F和R,头指针F总是指向队头元素的前一位,尾指针R总是指向队尾元素的当前位置,则该循环队列职工的元素个数为(B )?

(F-R)%M

(R-F+M)%M

(F-R+M)%M

R-F-1

书中定义的队列长度为:(rear-front++QueueSize)%QueueSize 1.rear: 定义中是指向末尾元素的下一个位置, 本题中是直接指向末尾元素, 所以将rear向后移动一个位置, R-1 2.front:定义中是指向首元素, 而本题中是指向首元素的前一个元素, 因此向后移动一个位置, F-1 rear = R-1 front = F-1 所以: [ (R - 1) - ( F - 1) + M]%M = (R-F+M)%M

23 现有一循环队列,其队头指针为front,队尾指针为rear;循环队列长度为N。其队内有效长度为?(假设队头不存放数据) B

(rear - front + N) % N + 1

(rear - front + N) % N

(rear - front) % (N + 1)

(rear - front + N) % (N - 1)

24 循环队列存储在数据A[0…m]中,则入队时的操作为___D___ 。

rear=rear+1

rear=(rear+1)%(m-1)

rear=(rear+1)%m

rear=(rear+1)%(m+1)

入队(rear+1)%QueueSize
QueueSize=m+1

25 大小为MAX的循环队列中,f为当前对头元素位置,r为当前队尾元素位置(最后一个元素的位置),则任意时刻,队列中的元素个数为 B

r-f

(r-f+MAX+1)%MAX

r-f+1

(r-f+MAX)%MAX

【这一题有点陷阱】我来解释下为什么是B而不是D
教材上说的 (也是大家记住的)求队列公式为: (rear-front+Max)%Max
该公式中的 rear指向队尾元素的下一个位置 ,而本题中 r 指 向队尾元素位置

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ningmengshuxiawo/article/details/113183695