这是我的第一个问题,我希望每个人都很好。我不得不编写一个deque或双端队列的数组实现,但是在理解前方法的入队元素时遇到了一些麻烦,我通过摆弄一下来让它工作但是我仍然很难理解逻辑:
void addAtFront(E)
{
if ( front == 0 )
front = array.length - 1;
else
front = ( front - 1 ) % array.length;
array [front] = element;
count++;
}
有人可以在这里解释if语句中发生的事情吗?如果前面是0那么我们在数组的末尾一直添加一个元素?这不就像在后方排队一样吗?
答案 0 :(得分:3)
您正在使用所谓的循环数组来存储此双端队列。从本质上讲,您的逻辑工作方式使得用于存储队列的数组在结尾处循环并返回到开头,反之亦然。
当你需要在队列的前面添加一个元素时,你需要将它扩展到左边,但是当你在实际的数组实现开始时(也就是当前面索引为零时) ,它已经到了左边,因为它可以得到。解决方案是循环到最后,假装数组是一个大圆圈。
您可以在逻辑上这样做的原因是因为您的阵列和队列实际上并不相同;数组只包含你的队列。您可以使用前后变量作为跟踪阵列中队列元素的位置的方法。这意味着数组的最后一个元素不一定是队列中的最后一个元素。您的队列可以根据需要遍历并沿阵列增长。阵列对队列施加的唯一限制是大小;数组显然不能容纳比它大的队列。
所有这些,你应该有类似的循环逻辑,用于在队列的后面添加一个元素。我猜你已经基于这个::
做了else
front = ( front - 1 ) % array.length;
我假设你的addAtBack
方法有这一行:
back = (back + 1) % array.length;
该模数运算为您处理循环。如果后面超过数组的末尾(a.k.a.后面是array.length),模数会将后向索引设置为0,将其循环到数组的开头。不幸的是,模数运算并不能有效地反过来,因此为什么只需要将if语句添加到前面。您应该可以从addAtFront
方法中移除该模数操作,并将该行替换为front--;
。