循环队列用数组A[0,m-1]存放其元素值,已知其头尾指针分别是front和rear,则当前队列中的元素个数是( )。
A. (rear-front+m)%m B. rear-front+1
C. rear-front-1 D. rear-front
给各位摸不着头脑的小伙伴们一个理解的办法,不要背:
注意:以下说的队列都是循环队列。
假设队列容量为M,即数组下标是[0,M-1]。
理论可以容纳M个元素——但是由于为了防止队空和队满的判断冲突,拿一个位置来进行区分【队空:front = rear;队满front = (rear + 1) % M】,这里比较重要,不懂的好好琢磨一下,会影响下面的理解。
循环队列中头指针front和尾指针rear的关系有两种,分别是
1.rear >= front,此时,可以直接用rear - front求得元素个数,自己画个图就能明白了;
2.rear < front,此时,用第一种方法显然不行,因为rear - front是负数,不对。这个时候,聪明的哥们你就会想到画个图,这样就能清晰地知道,| rear - front | 是空余的位置,所以这个时候我们用队列的容量减去front和rear差的绝对值不就是被占用的位置了吗,也就是元素个数。
好的,那么就可以写成M - | rear - front |,我们知道rear - front小于0,那么进一步写成M - (front - rear),再去掉括号调整一下位置变成了rear - front + M。
好啦,这样两种情况下的队列元素个数的计算就有着落了,但是细心一些的哥们会发现,两个式子之间存在着某种联系(都有rear - front)。是的,在编程时,为了统一判断,省去区分的条件而优化代码结构,就为1式的rear - front加上了一个M变成rear - front + M和2式一致,但是又会超过表示范围,结果就不对了,所以还需要一个操作使得这个M加了和没加一样,就有了计算后得到的结果对M取余的这个操作(M%M=0不就是白给吗),最后得到统一的式子:
( rear - front + M ) % M
怎么样是不是很神奇,但是可能有哥们有疑惑了:那也不对啊,队列的容量上限不是M-1吗,你刚刚也说了有一个位置要拿去作为区分队空和队满的条件啊,为什么2式不是加上(M-1)呢?这里呢,就要你自己去好好琢磨了,在编程的时候如果队列不为空,那么rear指针是根本不会等于front指针的,这个时候你可以将队列的容量看作M而不是M-1,但实际上为了区分判空的条件,将队列的最后一个元素(比较抽象,不是下标的最后一个,而是front前面那一个)作为检测队列是否满的条件。当rear指针指向front前面的那个位置时,如果有入队请求,是会失败的(因为若是入队,将这个元素存入rear位置,那么rear移动到front这个时候它俩贴住了,你说队列是空还是满?),所以说没看明白的话多自己琢磨,期待你开悟的那天,那么循环队列的这点分数就牢牢握在手中咯。
正常情况是尾减头,但是循环队列可能会出现队尾指针在队头指针的前面,
即“队尾-队头<0”的情况,所以多加个Maxsize再取余就好了。
a
A
正常情况是尾减头,但是循环会存在尾在头后面,那就加多个m,再取余
用户登录可进行刷题及查看答案
登录后提交答案