Java Queue 的 isFull 方法实现,不带 nitems 字段



我正在浏览Java算法书籍。实现队列的一种方法之一是使用NITEMS字段,以检查队列是空还是完整。以下是我试图缠绕头的方法。我试图通过在白板上绘制阵列等来理解这一点。

你们中的任何一个都可以在下面的代码上阐明一些启示吗?感谢您抽出宝贵的时间来看看这个。

public boolean isFull() // true if queue is full
{
return ( rear+2==front || (front+maxSize-2==rear) );
}

其他注释:

在具有带有nelems的队列的这种实现方式中,数组的大小,即" maxsize"是(排队 1),例如。对于5个元素的队列尺寸,最大尺寸为6。其他数组元素用于解析队列似乎是空的,同时又满了。

其中"后方"字段是阵列上的位置,并且在队列为FIFO时将新元素插入队列时会更新。"插入新元素时不会更新前面。

" front"字段是队列中第一个元素的位置,即在调用remove方法时会弹出的元素。

以下是本书中的完整算法,以防我的解释不清楚。我认为我了解ISEMPTY方法,但是Isfull方法对我来说并不清楚。

class Queue
{
private int maxSize;
private long[] queArray;
private int front;
private int rear;
//--------------------------------------------------------------
public Queue(int s) // constructor
{
maxSize = s+1; // array is 1 cell larger
queArray = new long[maxSize]; // than requested
front = 0;
rear = -1;
}
//--------------------------------------------------------------
public void insert(long j) // put item at rear of queue
{
if(rear == maxSize-1)
rear = -1;
queArray[++rear] = j;
}
//--------------------------------------------------------------
public long remove() // take item from front of queue
{
long temp = queArray[front++];
if(front == maxSize)
front = 0;
return temp;
}
//--------------------------------------------------------------
public long peek() // peek at front of queue
{
return queArray[front];
}
//--------------------------------------------------------------
public boolean isEmpty() // true if queue is empty
{
return ( rear+1==front || (front+maxSize-1==rear) );
}
//--------------------------------------------------------------
public boolean isFull() // true if queue is full
{
return ( rear+2==front || (front+maxSize-2==rear) );
}
//--------------------------------------------------------------
public int size() // (assumes queue not empty)
{
if(rear >= front) // contiguous sequence
return rear-front+1;
else // broken sequence
return (maxSize-front) + (rear+1);
}
//--------------------------------------------------------------
} //

谢谢!
raghu

可视化此实现的最佳方法是写下测试用例并查看它。假设我们的队列为4:

  • 前= 0
  • 后= -1
  • s = 4
  • maxsize = 5
  • Quearray是一个带有索引0到4的数组。

由于此实现是阵列的包裹,因此您可以在后方或前方前方的索引中进行后方。这就是为什么Isempty()和Isfull()都有两个案例的原因。我将以两个示例进行演示 - 一个我们用4个插入物填充数组,另一个插入2个插入物,1个删除,3个插入物,1个删除和1个插入物。令q为quearray,r为后方,f是前面:

  • q = [0,0,0,0,0] f = 0 r = -1

    这是起始位置。在这一点上,在插入之前,队列为空 - 您可以使用ISEMPTY()和后部 1 ==前部有效,因为-1 1 ==0。

  • q = [5,0,0,0,0] f = 0 r = 0

    第一个插入物将后部最大为0。

  • q = [5,4,0,0,0] f = 0 r = 1

    第二插入将后部带到1。

  • q = [5,4,3,0,0] f = 0 r = 2

  • q = [5,4,3,2,0] f = 0 r = 3

请注意,在这一点上,队列已满 - 它包含4个元素。呼叫isfull()您会看到条件前 maxsize-2 ==后方是正确的:0 5-2 == 3。

现在,让我们尝试包裹的方法,后部到达前后的索引。让我们从第二个插件开始:

  • q = [5,4,0,0,0] f = 0 r = 1

  • q = [0,4,0,0,0] f = 1 r = 1

    第一个删除。为了示例,我实际上将" 5"从数组中删除到" 0" - 实际上并未在此实现中发生," 5"在那里,但会在需要时被覆盖。但是为了可视化是有效的。

  • q = [0,4,3,0,0] f = 1 r = 2

  • q = [0,4,3,2,0] f = 1 r = 3
  • q = [0,4,3,2,1] f = 1 r = 4
  • q = [0,0,3,2,1] f = 2 r = 4
  • q = [5,0,3,2,1] f = 2 r = 0

    此刻我们终于包裹了 - 后方在前后,我们在队列中有四个元素!现在查看Isfull()的另一个条件是:后 2 ==正面为0 2 == 2。

我希望这有助于说明解决方案的工作原理,而无需实际计算元素。

最新更新