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];
}
}