我们刚刚在课堂上学习循环队列,我有几个问题。 因为我们将尾部定义为最后一个值旁边的空白空间,如下所示:
|1| |3|4|5|6|
头部将指向数字3,尾部将指向1到3之间的空白区域。我很困惑如果该空间被填满会发生什么,例如下面:
|1|2|3|4|5|6|
然后头部仍然指向3,但是尾部需要指向前面空白框之后的下一个框,因此它将指向3或标题。我该怎么办呢?
答案 0 :(得分:6)
发生这种情况时,您的队列已满。在处理可以推送的新项目时,您有几个选择:
丢弃推送事件:仅当弹出其他项目时,现在可以再次按下项目。 <{1}}和head
均未更新。
示例:考虑已填满的事件队列,简单忽略新请求。
丢弃(弹出)队列中最早的事件:在这种情况下,您将两个更新为tail
和head
指针。
示例:缓冲从网络摄像头接收图像帧以进行处理。对于“实时”Feed,您可能更喜欢在处理过程中丢弃较旧的帧。
创建一个更大的队列:即,动态分配更多内存
示例:您使用循环队列,因为它是一种高效的实现,在您推送项目时,大多数情况下不需要内存分配。但是,您不希望丢失队列中的项目,以便允许偶尔重新分配更多内存
正确的行动取决于您的申请。
PS。:您的实施基于在队列中保留一个空槽来区分完整和空缓冲区。另一种选择是保持队列中元素数量的计数器以进行区分。更多信息可以在Circular buffer (Wikipedia)找到。
答案 1 :(得分:3)
正如我所想,圆形队列部分是圆形的,因为它没有“填满”。它将始终保持一定数量的元素,根据需要丢弃旧元素。
所以你永远不会填满空地;如果你插入一个新元素,你将删除一个旧元素,因此仍然会有一个空格。
换句话说,在你的图表中,如果你插入一个新的数字,比如0,你的队列看起来如下(假设1
是最后一个元素,3
是第一个元素:
|1| |3|4|5|6|
它将如下所示:
| |0|3|4|5|6|
但是,圆形队列的某些实现只会在达到其全长时抛出异常/错误,如果这是您想要的。请查看示例this。
答案 2 :(得分:0)
以下是关于队列的最简洁的解释 曾经发现过。您可以根据此扩展队列 基础。资料来源:“算法”,作者:Robert Sedgewick。
const max = 100;
var queue: aray[0..max]of integer;
head,tail: integer;
procedure put(v:integer);
begin
queue[tail] := v;
tail := tail + 1;
if (tail > max) then tail := 0;
end;
function get: integer;
begin
get := queue[head];
head := head + 1;
if (head > max) then head := 0;
end;
procedure queueinitialize;
begin
head := 0;
tail := 0;
end;
function queueempty: boolean;
begin
queueempty := (head = tail);
end;
“有必要维护两个索引,一个到队列的开头(头部),一个到结尾(尾部)。队列的内容是头部和尾部之间数组中的所有元素,考虑到当遇到数组的末尾时,将“环绕”重新设置为0。如果head = tail,则队列被定义为空;如果head = tail + 1, 或tail = max和head = 0,它被定义为已满。“
答案 3 :(得分:0)
当头部和尾部指向同一个地方时,我们说队列已满。可以添加更多元素。要添加任何元素,您必须从队列中删除一个元素。这样头部将会增加并再次生成空格。