一.简介
每次数据出队后都把数据往前移动将是非常低效的,使用环形队列将大幅提高数据出队效率。
使用front、rear 分别记录数据出队、入队索引位置,只有在队列满了之后才需要扩容移动数据
二.实现
package com.vincent;
import java.util.Arrays;
import java.util.NoSuchElementException;
public class ArrayQueue<T> {
private static final int DEFAULT_CAPACITY = 16;
private int front;
private int rear;
private int size;
private T[] elements;
public ArrayQueue(){
elements = (T[])new Object[DEFAULT_CAPACITY];
}
public ArrayQueue(int capacity){
if(capacity <=0 ){
throw new IllegalArgumentException("容量必须大于0");
}
//确保容量为2的次方
int i = 1;
while(i < capacity){
i = i << 1;
}
elements = (T[])new Object[i];
}
public void add(T item){
//对数组扩容
if(size == elements.length){
T[] tmp = (T[])new Object[elements.length << 1];
if(rear > front){
System.arraycopy(elements,front,tmp,0,rear-front);
}
else{
System.arraycopy(elements,front,tmp,0,elements.length-front);
System.arraycopy(elements,0,tmp,elements.length-front,rear);
rear = elements.length;
}
front = 0;
elements = tmp;
}
elements[rear++] = item;
rear %= elements.length;
size++;
}
public T popLeft(){
if(size == 0){
throw new NoSuchElementException("队列为空");
}
T item = elements[front];
elements[front++] = null;
front %= elements.length;
size--;
return item;
}
public int size(){
return size;
}
@Override
public String toString() {
return Arrays.toString(elements);
}
public static void main(String[] args) {
ArrayQueue<Integer> queue = new ArrayQueue<>();
for(int i=0;i<20;i++){
queue.add(i);
}
for(int i=0;i<10;i++){
System.out.print(queue.popLeft() + "\t");
}
System.out.println();
System.out.println(queue);
for(int i=20;i<20+20;i++){
queue.add(i);
}
System.out.println(queue);
}
}
效果:
三.总结
使用环形队列将在数据出队时有效提高效率