循环队列的作用: 在性能方面, 无需顺序队列的数据搬移过程
循环队列的实现关键: 确定队列为满还是为空
- 1, 队列满的条件:
(tail指针+1)%数组长度 = head指针
; - 2, 队列空的条件:
head指针 = tail指针
.
(注: 以上指针为数组下标位置)
问题解释: 为什么确定队列满这个点检的时候, 要使用"tail指针+1", 然后再去模"数组长度",
直接用tail==head做判断不是很简单明确吗?解释: 在一种位置下, 假设的tail==head不容易实现, head=1, tail=0的时候, 看官计算一下,
是不是假设的公式不可行了,这个时候(0+1) % 数组长度 = 1
还是成立的.
确定了关键点, 代码实现就容易的多了, talk is cheap, show you the code.
/**
* 功能说明:循环队列
* 开发人员:@author MaLi
*/
public class CircleQueue {
private Object[] container;
private int head;
private int tail;
private int length;
public CircleQueue(int length) {
this.length = length+1;
this.container = new Object[this.length];
this.head = 0;
this.tail = 0;
}
/**
* 出队
* 队列为空条件: head与tail相等
*
* @return 队列的head位置元素
*/
public Object deQueue() {
Object result = null;
if (head == tail) {
return null;
} else {
result = container[head];
container[head] = null;
//check: head是否在0位置
head = head == (length - 1) ? 0 : ++head;
}
return result;
}
/**
* 入队
* 队列为满条件: (tail+1)%length=head
* +1的目的: 防止tail在0的位置
* tail始终指向
*
* @param element 入队元素
*/
public boolean enQueue(Object element) {
if ((tail + 1) % length == head) {
return false;
} else {
container[tail] = element;
tail = tail == (length - 1) ? 0 : ++tail;
return true;
}
}
}
测试代码
import org.junit.Test;
/**
* 功能说明:
* 开发人员:@author MaLi
*/
public class CircleQueueTest {
@Test
public void testMethod1() {
CircleQueue queue = new CircleQueue(5);
for (int i = 0; i < 6; i++) {
boolean b = queue.enQueue(i);
System.out.println(i + " 入队--> " + b);
}
for (int i = 0; i < 2; i++) {
Object o = queue.deQueue();
System.out.println(i + " 出队--> " + o);
}
for (int i = 0; i < 6; i++) {
boolean b = queue.enQueue(i);
System.out.println(i + " 入队--> " + b);
}
}
}