(tail + 1) % data.length == front
来源:2-7 循环队列的实现
545484sa54
2021-03-23 22:29:56
如Capacity初始化长度为10(实际长度+1=11)。
入队6条数据,tail = 6 。
出队3条数据 front = 3。
入库1条数据,tail = 7。
。。。
继续入库3条数据,tail = 10。
此时(tail + 1) % data.length =(10 + 1) % 11 = 0,front = 3,不等式成立,不触发扩容操作,数组实际长度依然为11。
继续入库 tail = 11,data[tail(11)] 产生数组越界。
这个问题可能是在某个点没有仔细观看老师的视频导致的,不过依然希望麻烦老师进行一个解惑,谢谢老师。
2回答
ccchloe
2021-05-19
@Override
public void enqueue(E e){
if ((tail + 1) % data.length == front )
resize(2 * getCapacity() );
data[tail] = e;
tail = (tail + 1) % data.length;
size ++;
}
enqueue方法中,数据进入队列之后,tail的变化是:
tail = (tail + 1) % data.length;
也就是说tail根本不可能取到11,所以也就不会越界,这也是为什么要取余。取余就是要让tail等于data.capacity时,能够从头开始。
(这是我的想法啊,不知道我说清楚没,要是有错误轻喷啊,欢迎交流~)
liuyubobobo
2021-03-24
对于你说的样例,在 tail = 10 的时候,继续入队一个元素。
先执行 40 行,data[tail] = e。此时,tail = 10,没有越界,这句话没有问题;
然后,执行 41 行,tail = (tail + 1) % data.length。此时,tail 被置为了 0。表示如果下次再有新的元素,就应该放到 0 了(而不是 11)。
==========
你已经想出了一个很完整的用例,非常赞。实际上使用你想的用例,在程序上执行一下,看看是否有问题?
如果没有问题,是用单步跟踪的方式,去跟踪一下,观察一下在每一步,程序的每一个变量在如何变化?尤其是自己认为会出问题的地方,程序为什么没有出问题?自己的想法哪里错了?
这是学习算法,乃至学习计算机非常重要的方式。很多时候不能靠想,一定要亲自去尝试,才能找到自己的思维漏洞。久而久之,才能慢慢做到靠眼睛 debug。
继续加油!:)
相似问题