完整的循环队列?

时间:2012-07-05 20:53:22

标签: queue

我们刚刚在课堂上学习循环队列,我有几个问题。 因为我们将尾部定义为最后一个值旁边的空白空间,如下所示:

|1| |3|4|5|6|

头部将指向数字3,尾部将指向1到3之间的空白区域。我很困惑如果该空间被填满会发生什么,例如下面:

|1|2|3|4|5|6|

然后头部仍然指向3,但是尾部需要指向前面空白框之后的下一个框,因此它将指向3或标题。我该怎么办呢?

4 个答案:

答案 0 :(得分:6)

发生这种情况时,您的队列已满。在处理可以推送的新项目时,您有几个选择:

  1. 丢弃推送事件:仅当弹出其他项目时,现在可以再次按下项目。 <{1}}和head均未更新。

      

    示例:考虑已填满的事件队列,简单忽略新请求。

  2. 丢弃(弹出)队列中最早的事件:在这种情况下,您将两个更新为tailhead指针。

      

    示例:缓冲从网络摄像头接收图像帧以进行处理。对于“实时”Feed,您可能更喜欢在处理过程中丢弃较旧的帧。

  3. 创建一个更大的队列:即,动态分配更多内存

      

    示例:您使用循环队列,因为它是一种高效的实现,在您推送项目时,大多数情况下不需要内存分配。但是,您不希望丢失队列中的项目,以便允许偶尔重新分配更多内存

  4. 正确的行动取决于您的申请。

    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)

当头部和尾部指向同一个地方时,我们说队列已满。可以添加更多元素。要添加任何元素,您必须从队列中删除一个元素。这样头部将会增加并再次生成空格。