循环队列声称未检索的项目将被覆盖


class CircularQueue{
    private char q[];
    private int putloc, getloc;
    public CircularQueue(int size){
      q = new char[size+1];
      putloc = getloc = 0;
    }
    public void put (char ch) {
      if (putloc+1==getloc | ((putloc ==q.length-1) & (getloc==0))) {
        System.out.println ("Queue is full.");
        return;
      }
      putloc++;
      if(putloc==q.length) putloc = 0;
      q[putloc] = ch;
    }
    public char get() {
      if (getloc == putloc){
        System.out.println("Queue is empty.");
        return (char) 0;
      }
      getloc++;
      if(getloc==q.length) getloc =0;
      return q[getloc];
    }
  }

我不明白队列什么时候会满。

如果putloc == q.length-1,它将位于数组的末尾。
getloc == 0将位于数组的开头。
因此,如果调用put(),它将执行putloc++并转到q[0]并在那里放置一个值。
他们声称它会覆盖q[0]的值,但如果getloc == 0,则意味着它已经从数组的该部分返回了一个值。
q[getloc]紧随getloc++因此一旦getloc == 0它将从q[0]中获取一个值,将该空间留空以放置新值。
因此,下次调用get()时,它将从q[1]中获取一个值。

有人可以解释一下我的逻辑在哪里错误吗?

您的声明:"如果getloc == 0,则意味着它已经从数组的该部分返回了一个值。问题是这并不总是正确的。在put()函数中,您有条件 if (putloc+1==getloc || ((putloc ==q.length-1) && (getloc==0))) .如果数组是满的,但从来没有人调用过get(),那么((putloc ==q.length-1) && (getloc==0))将等于true,没有任何值被返回。

另外两个要解决的问题:

-使用&&||,而不是&|。两个标记表示布尔运算,一个标记用于位操作。
-编写的此代码不是线程安全的。如果一个线程同时调用get()而另一个线程调用put(),则getloc和/或putloc将不准确。为了解决这个问题,我会使用synchronized

public void put (char ch) {
    synchronized(q) {
      if (putloc+1==getloc | ((putloc ==q.length-1) & (getloc==0))) {
        System.out.println ("Queue is full.");
        return;
      }
      putloc++;
      if(putloc==q.length) putloc = 0;
      q[putloc] = ch;
   }
}
public char get() {
  synchronized(q) {
      if (getloc == putloc){
        System.out.println("Queue is empty.");
        return (char) 0;
      }
      getloc++;
      if(getloc==q.length) getloc =0;
      return q[getloc];
  }
}

最新更新