循环队列
1、原理:循环队列就是将队列存储空间的最后一个位置绕到第一个位置,形成一种理解意义上的环结构,在循环队列结构中,当存储空间的最后一个位置已被使用而再要进入队运算时,只需要存储空间的第一个位置空闲,便可将元素加入到第一个位置,即将存储空间的第一个位置作为队尾。
2、循环队列的实现:
首先。需要引入两个指向,来标记队首和队尾
(start标记队首,end标记队尾)
接下来我们就往里面添加元素(如下图所示)
如果要实现循环队列,当队的最后一个位置有元素,添加下个元素到队首,此时队首的位置必须的空出来才能循环起来:
然后依次循环下去。
在实现的过程中肯定会涉及到数组的扩容以及缩减问题,下面我来解释一下数组何时需要扩容(缩减)以及如何扩容(缩减)。
以扩容为例:再循环过程中,出现end即将要覆盖start的时候需要扩容(如下图:)
缩减原理相同。接下来我们看代码实现:
public class CilQueDemo {
private int[] arr = new int[20];//假定数组长度为20
private int start = 0;
private int end = 0;
//循环队列增加元素操作
public void add(int a){
arr[end % arr.length] = a; //因为考虑到队列的循环,end的值会超过数组的长度,而数组下标不能超,因此采取取余的手段
end++;
//数组扩容
if(end - start + 1 == arr.length){
int[] arrnew = new int[arr.length * 2];
for(int i = 0; i < arr.length; i++){
arrnew[i] = arr[(i + start) % arr.length];
}
arr = arrnew; //采用数组拷贝来扩充数组
end = end - start;
start = 0;//指向数组头部
}
}
//删除操作
public void del(){
if(end == start){
System.out.println("null");
return ;
}
System.out.println(arr[start % arr.length]);
start++;
//数组缩减
if(end - start + 1 < arr.length/4) {
int newlen = arr.length/2;
if(newlen<20) { //定义数组长度最低不少于20
newlen = 20;
}
int[] arrnew = new int[newlen];
for(int i=0;i<arrnew.length;i++) {
arrnew[i] = arr[(start + i)%arr.length];
}
arr = arrnew;
end = end - start;
start = 0;
}
}
}