【问题标题】:Java Queue's isFull method implementation without nitems fieldJava Queue 的 isFull 方法实现没有 nitems 字段
【发布时间】:2017-09-28 17:49:57
【问题描述】:

我正在阅读一本 java 算法书。实现队列的一种方法是不使用 nitems 字段来检查队列是空的还是满的。以下是我试图绕过的方法。我试图通过在白板上绘制数组等来理解这一点,但没有清楚的理解。

你们中的任何人都可以对下面的代码有所了解吗?感谢您花时间看这个。

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

补充说明:

在这种没有 nelem 的队列实现方式中,数组的大小,即“maxSize”为 (queuesize+1),例如对于 5 个元素的队列大小,maxSize 将为 6。额外的数组元素用于解决队列同时显示为空和满的情况。

其中“rear”字段是数组中的位置,当有新元素插入队列时,它会更新,因为队列是先进先出的。 "插入新元素时不会更新front。

“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);
}
//--------------------------------------------------------------
} //

谢谢!
拉古

【问题讨论】:

  • 算法很有意思,谢谢分享!我用一个例子写了一个答案,展示了 isFull() 的工作原理。如果您觉得不错,我可以请您通过单击答案旁边的灰色复选标记将其变为绿色来接受答案吗?也非常感谢您的支持:-)
  • @Assafs 记住新手在某些时候接受答案是很好的。但是请:给他一些时间来消化你的意见。在写完答案后 1 分钟提出此请求确实是常见的赞赏做法。
  • 我明白了,我不是故意的。感谢您的友好评论。

标签: java arrays queue


【解决方案1】:

可视化此实现的最佳方法是写下一个测试用例并查看它。假设我们有 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==front 有效,因为 -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() 你会看到条件 front+maxSize-2==rear 为真: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() 的另一个条件存在:rear+2==front as 0+2==2。

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

【讨论】:

  • 很好的解释!不过,我只有一件事不清楚您的回答。在最后一个环绕场景中,r 是如何从 r=3 跳转到 r=-1 的?
  • 很好的解释!不过,我只有一件事不清楚您的回答。在最后一个环绕场景中,r 是如何从 r=3 跳转到 r=-1 的?如果您看到队列的插入方法,除非 r==(maxsize-1) 它不会回到 -1,所以在这种情况下 r 应该是 4 才能回到 -1,我错过了什么吗?除此之外,其他一切我都清楚。
  • 你是对的,我在第二个例子中有一个错误。你需要先到4。我纠正了它。现在清楚了吗?
  • 感谢您抽出时间向我解释这一点。这正是我所需要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-30
  • 1970-01-01
  • 2021-12-20
  • 2011-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多