用数组实现循环队列(新思路)
用数组实现一个循环队列,比较难的一个点就是如何判断数组是否满了,不论是书上的方法,还是一些大佬的写法,都是利用一个计算去判断:(rear + maxSize - front) % maxSize
有的小伙伴天资聪颖一下就理解了,有的小伙伴可能理解不够深刻,只能牢牢记住这个公式
在这里我给大伙分享一种思路:
其实上面的思路的本质就是:判断尾指针是否追上了头指针,很多小伙伴可能就在你追我,我追你的过程中就懵逼了
其实我们完全可以忽略这个过程,我们只需要定义一个变量 size,add() 一个元素我就 size++,poll() 一个元素我就 size--,只要 size 是小于队列的最大长度,就说明是可以 add() 的。
具体可以看下代码:
public class RingQueue {
public static class MyQueue{
private int[] arr;
private int size;
private final int limit;
// put 元素的位置
private int putIndex;
// poll 元素的位置
private int pollIndex;
public MyQueue(int limit) {
arr = new int[limit];
putIndex = 0;
pollIndex = 0;
size = 0;
this.limit = limit;
}
public void add(int value) {
// 只要 size != limit 就说明还有空间可以添加元素
if (size == limit) {
throw new RuntimeException("队列已满");
}
arr[putIndex] = value;
size++;
// 计算下一个放入元素的位置
putIndex = nextIndex(putIndex);
}
public int poll() {
// 只要 size != 0,就说明还有元素可以 poll
if (size == 0) {
throw new RuntimeException("队列为空");
}
int ans = arr[pollIndex];
size--;
// 计算下一个 poll 元素的位置
pollIndex = nextIndex(pollIndex);
return ans;
}
/**
* 计算下一个 put,poll 元素的位置
* 如果当前元素所在的位置还没到数组的最后一个位置,那就 i++
* 如果当前元素所在的位置已经是数组的最后一个位置了,那下一个位置就是数组的开头 0
* @param i 当前元素的位置
* @return
*/
public int nextIndex(int i) {
return i < limit - 1 ? i + 1 : 0;
}
}
public static void main(String[] args) {
MyQueue queue = new MyQueue(10);
queue.add(1);
queue.add(2);
queue.add(6);
queue.add(4);
queue.add(7);
queue.add(2);
queue.add(9);
System.out.println(Arrays.toString(queue.arr));
System.out.println("弹出元素:" + queue.poll());
System.out.println("弹出元素:" + queue.poll());
System.out.println("弹出元素:" + queue.poll());
System.out.println("弹出元素:" + queue.poll());
System.out.println("队列中还剩 " + queue.size + " 个元素");
}
}
如果说在做算法题的过程中,需要自己实现数据结构,通常我们可以定义一些额外的变量来简化我们的某些操作