背景:有一个人接收到的一个面试题,说写一个环形队列。
其实它描述的并非环形队列,而是普通的ArrayQueue。
先贴代码.
这里,队列空,dequeue会报错,队列满,enqueue会报错。
你会发现,这个跟arrayQueue,几乎一样,看起来是环形的结构,但是总感觉不对劲。
而且,你去看arrayQueue的源代码,会发现,思想几乎一样。。。
只是,少了arrayQueue的扩容机制。
public class DiyArrayQueue implements Queue {
private static final int MAX_ARRAY_SIZE = 65536;
private Object[] items;
// 头节点,get的位置
private int front;
// 尾节点,put的位置
private int rear;
public DiyArrayQueue(int initQueueSize){
// 容量+1,因为,尾节点永远不会追上头节点,也就是实际容量少了1.
items = new Object[initQueueSize + 1];
this.rear = 0;
this.front = 0;
}
@Override
public boolean enqueue(Object o) {
int tmp = rear;
if(++tmp == items.length){
tmp = 0;
}
if(tmp == front){
throw new RuntimeException("队列是满的");
}
rear = tmp;
items[rear] = o;
return true;
}
@Override
public Object dequeue() {
if(rear == front){
throw new RuntimeException("队列是空的");
}
int tmp = front + 1;
if(tmp == items.length){
tmp = 0;
}
Object o = items[tmp];
if(o == null){
return null;
}
front = tmp;
return o;
}
@Override
public int size() {
if(rear == front){
return 0;
}
int size = rear - front;
if(size < 0){
return items.length - front + rear;
}
return size;
}
}
我觉得,要环形队列,最起码,应该是会一直循环的吧,比如,可以一直enqueue。
像这样:
虽然我觉得这样也不对。
public class CircleQueue implements Queue {
private static final int MAX_ARRAY_SIZE = 65536;
private Object[] items;
// 头节点,get的位置
private int front;
// 尾节点,put的位置
private int rear;
public CircleQueue(int initQueueSize){
items = new Object[initQueueSize];
this.rear = 0;
this.front = 0;
}
@Override
public boolean enqueue(Object o) {
if(++rear == items.length){
rear = 0;
}
items[rear] = o;
return true;
}
@Override
public Object dequeue() {
int tmp = front + 1;
if(tmp == items.length){
tmp = 0;
}
Object o = items[tmp];
if(o == null){
return null;
}
front = tmp;
// 设置空
items[tmp] = null;
return o;
}
@Override
public int size() {
// 空和full这两个指针都是指向相同的元素
if(rear == front){
// 如果有一个元素为null,则说明null的
if( null == items[0]){
return 0;
}
return items.length;
}
int size = rear - front;
if(size < 0){
return items.length - front + rear;
}
return size;
}
}
总结:
1、这种数据结构,必须要定位使用场景,否则,很容易出现误解。
比如环形队列在延迟队列中得使用,就会是另一个环形队列得数据结构了。
2、而且,比如,有时候环形队列用链表会更合适,没有扩容得烦扰什么的。
网友评论