【问题标题】:logic of array based queue in CC中基于数组的队列逻辑
【发布时间】:2015-02-02 02:26:54
【问题描述】:

我在网上阅读时碰巧遇到了基于数组的队列的实现:

#include <stdio.h>
#include <stdlib.h>

typedef int item_t;
typedef struct {item_t *base; 
                int    front; 
                int     rear; 
                int     size;} queue_t;

queue_t *create_queue(int size)
{   queue_t *qu;
    qu = (queue_t *) malloc( sizeof(queue_t) );
    qu->base = (item_t *) malloc( size * sizeof(item_t) );
    //printf("q->base address %p\n",qu->base);
    qu->size = size;
    qu->front = qu->rear = 0;
    return( qu );
}

int enqueue( item_t x, queue_t *qu)
{   
    printf("modulo result %d\n",((qu->rear +2)% qu->size));
    if ( qu->front != ((qu->rear +2)% qu->size) )
    {   qu->base[qu->rear] = x; 
        qu->rear = ((qu->rear+1)%qu->size);  
        return( 0 );
    }
    else
       return( -1 );
}

这是代码中的创建队列和入队逻辑。最初 front 和 back 是 zero.qu->front 和 ((qu-&gt;rear +2)% qu-&gt;size) 不相等,因此项目将被排队。我无法理解为什么在这个逻辑中使用 2 - ((qu-&gt;rear +2)% qu-&gt;size)

【问题讨论】:

  • 当元素到达数组的“顶部”时,它会“包裹”。
  • 如果我选择基于数组的队列的大小为 4 ,那么按照上述逻辑我只能将 2 个元素加入队列?
  • 我没有仔细研究过算法。可能是最后几个元素从未分配过。但它是队列算法的典型“包装”。替代方法是要么在到达顶部时完全用完新元素,要么在从底部移除元素时停止并向下复制元素。
  • 对于这种队列,检查队列本身是否“溢出”并即将“吞下它的尾巴”可能非常棘手。这可能是设计中最容易出错的部分。有一些方法可以使用所有元素,但如果不使用最后一对可以简化检查,那么这可能是一个很好的权衡。
  • 如果我使用 ((qu->rear +1)% qu->size) 而不是 ((qu->rear +2)% qu->size) ,我将能够入队基于数组的大小为 4 的队列有 3 个项目。那么为什么不使用 1 进行包装,而是使用 2 呢?

标签: c pointers data-structures


【解决方案1】:

因为如果 (qu->rear+1) % qu->size 被使用,并且一个元素将在几乎满的队列中排队,那么 q->rear 将被递增(这是在“qu- >rear = ((qu->rear+1)%qu->size);") 并且您会遇到满队列与空队列无法区分的情况。

说队列大小为 4 个元素,然后添加 4 个实际元素,最终会得到“前”指向第 0 个元素(因为前从未改变),“后”将再次指向第 0 个元素作为“后”增加了 4 次,在最后一次增加时它回绕回 0。在这种情况下,前和后指向第 0 个元素,这与队列为空时开始时相同,您无法判断队列是满还是空,即一个问题(有时)。

此代码可能会稍作更改,以反映设置队列时的队列大小参数并不意味着您创建了大小为 N 的队列,而是创建了大小为 N-1 的队列......

【讨论】:

  • 谢谢,所以通过上述逻辑,我可以将 3 个项目排入队列,以获取 4 的大小?如果是,当我的第二个项目入队时,后面的值为 2,现在如果我继续插入 3 个项目,这个条件将不满足 - if ( qu->front != ((qu->rear +2)% qu->size) ) ,因此只能添加 2 个元素,对吗?
猜你喜欢
  • 2018-01-31
  • 2011-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多