循环队列
当插入的数据时,如果后边数据满了,前边有数据出队列了,我们需要用循环队列,把数据放到前边。当所有队列区域都被填满时,我们再扩容。
如图如果我们要插入1-14时。如果插11、12、13、14时
我们需要把11、12、13、14插到前面位置。
为了达到该目的我们需要定义入队指针(f)和出队指针(s)
当1出队,并要插入11时我们需要让f重新指向队列0的位置(这里一定不要写f=0)
arr[f % arr.length] = value;
f++;
插入10后f等于10了只要让f % arr.length就能实现把11赋到队列0位置了(实现了循环输入)
当插入11后如果2没出队列,就说明了队列已经满了。此时f=s+arr.length。
出队列s的条件和j一样
System.out.println(arr[s % arr.length]);
s++;
当10输出后需要让11重新输出队列0的值。s% arr.length就能实现循环输出了。
当11也输出后列表为空。s等于f
当需要扩容时我们需要建一个新队列接值,再赋给之前队列。如下图
if (f - s == arr.length) {
int[] brr = new int[arr.length * 2];
for (int i = s; i < f; i++) {
brr[i % brr.length] = arr[i / arr.length];
}
arr = brr;
}
i % brr.length和i / arr.length都是为了循环输出
代码
public class Xhduilie {
private int arr[] = new int[10];
//入队指针
private int f = 0;
//出队指针
private int s = 0;
public void add(int value) {
//如果队尾和队头指针相差一个数组长度,进行扩容
if (f - s == arr.length) {
int[] brr = new int[arr.length * 2];
for (int i = s; i < f; i++) {
brr[i % brr.length] = arr[i / arr.length];
}
arr = brr;
}
arr[f % arr.length] = value;
f++;
}
public void get() {
if (s == f) {
System.out.println("没数了");
return;
}
System.out.println(arr[s % arr.length]);
s++;
}
}
泛型
泛型即泛指任何类型,允许在定义类、接口、方法时使用类型形参,这个类型形参(或叫泛型)将在声明变量、创建对象、调用方法时动态的指定(即传入实际的类型参数,也可称为类型实参)
public class 类名<泛型名>{
//下面定义了一个数组,当实例化这个类时,在<>尖括号内写什么类型那这个数组就是什么类型的。
//泛型名一般是使用E、T表示的,也可以使用其他名字。
private 泛型名[] arr=(泛型名[])new Object[10];
}
上面循环队列我们用int写的,当我们输入string类型或浮点型的都会报错,所以我们就可以使用泛型。
循环队列代码(泛型)
public class Queue<T> {
private T[] arr = (T[]) new Object[10];
private int f = 0;
private int s = 0;
public void add(T value) {
if (f - s == arr.length) {
return;
}
arr[f % arr.length] = value;
f++;
}
public void get() {
if (s == f) {
System.out.println("没数了");
return;
}
System.out.println(arr[s % arr.length]);
s++;
}
}
我们这样输入什么都不会报错了。