框架:
class MyCircularQueue {
public MyCircularQueue(int k) {
}
public boolean enQueue(int value) {
}
public boolean deQueue() {
}
public int Front() {
}
public int Rear() {
}
public boolean isEmpty() {
}
public boolean isFull() {
}
}
循环队列的结构:
循环队列要求头尾相接,我们可以理解为一个圆形储存器
一.构造队列
public int elem[];
//int usedSize;
public int front;//队首
public int rear;//队尾
public Boolean tmp = false;
public MyCycleQueue(int k) {
elem = new int[k];
}
二.解决isEmpty(),isFull()
解决这个问题有三种方法:
1. 通过添加 usedSize属性记录
2. 保留一个位置
3. 使用标记
1. 通过添加 usedSize属性记录
这个方法是最常规的,通过
public boolean isEmpty() {
return usedSize == 0;
}
public boolean isFull() {
return usedSize == elem.length;
}
2. 保留一个位置
就是通过在最后的位置空一个地方造成rear与front的差异完成判断
public boolean isEmpty() {
return front == rear;
}
public boolean isFull() {
return front == (rear + 1)%elem.length;
}
上述代码(rear + 1)%elem.length部分运用了数组下标循环的小技巧
*数组下标循环的小技巧
在index位置移动offset距离(小于 array.length)
index = (index + offset) % array.length
在index位置移动offset距离(大于 array.length)
index = (index + array.length - offset) % array.length
3. 使用标记
可以设置一个boolean类型数据
public Boolean tmp;
在最开始时是false,插入数据就变为true,移除数据后变为false
当!tmp && front == rear同时满足为空
public boolean isEmpty() {
//3. 使用标记
return (!tmp && front == rear);
}
public boolean isFull() {
//3. 使用标记
return (tmp && front == rear);
}
三.插入删除
1. 通过添加 usedSize属性记录
//向循环队列插入一个元素
public boolean enQueue(int value) {
if(isFull()) {
return false;
}
elem[rear] = value;
rear = (rear + 1)%elem.length;
usedSize++;
return true;
}
//从循环队列中删除一个元素
public boolean deQueue() {
if(isEmpty()) {
return false;
}
elem[front] = 0;
front = (front + 1)%elem.length;
usedSize--;
return true;
}
2. 保留一个位置
//向循环队列插入一个元素
public boolean enQueue(int value) {
if(isFull()) {
return false;
}
elem[rear] = value;
rear = (rear + 1)%elem.length;
return true;
}
//从循环队列中删除一个元素
public boolean deQueue() {
if(isEmpty()) {
return false;
}
elem[front] = 0;
front = (front + 1)%elem.length;
return true;
}
3. 使用标记
//向循环队列插入一个元素
public boolean enQueue(int value) {
if(isFull()) {
return false;
}
elem[rear] = value;
rear = (rear + 1)%elem.length;
tmp = true;
return true;
}
//从循环队列中删除一个元素
public boolean deQueue() {
if(isEmpty()) {
return false;
}
elem[front] = 0;
front = (front + 1)%elem.length;
tmp = false;
return true;
}
四.获取对首队尾
//从队首获取元素
public int Front() {
if(isEmpty()) {
return -1;
}
return elem[front];
}
//获取队尾元素
public int Rear() {
if(isEmpty()) {
return -1;
}
int index = (rear == 0) ? elem.length-1 : (rear -1);
return elem[index];
}