循环队列。顾明四姨~就像围成一个圈,有两个标记,一个头一个尾,从头出去从尾插入
定义front 和tail :
初始时front=tail=0,队列为空,当插进一个元素,tail循环加一。当走了一个,front循环加一。所谓循环加一,其实就是:如果tail队尾到了数组的末尾,这时数组的前端还有空的位置(每次出队一个元素front就循环加一【(front+1)%data.length】,导致数组前面位置为空),tail还可以回到数组前端进行插入,算法是: (tail +1)%data.length
代码:
package duilie; public class LoopQueue<E> implements Queue<E>{ private E[] data; private int front,tail; private int size; public LoopQueue(int capacity){ data = (E[])new Object[capacity + 1];//浪费一个空间换取效率 front = tail = 0;//相等时队列为空 size = 0; } //默认构造10的队列 public LoopQueue(){ this(10); } //获得队列长度 public int getCapacity(){ return data.length-1; } //判断是否为空 public boolean isEmpty(){ return front == tail; } //获取队列实际使用长度 public int getSize(){ return size; } //入队 public void enqueue(E e){ if((tail+1)%data.length == front){//如果队列满了 resize(getCapacity()*2);//圹容 } data[tail] = e;//将值添加到队尾 tail = (tail + 1) % data.length;//队尾循环加一 size++; } //出队 public E dequeue(){ if(isEmpty()){ throw new IllegalArgumentException("Cannot dequeue from an empty queue"); } E ret = data[front]; data[front]=null; front = (front + 1)%data.length;//队首循环加一 size--; if(size == getCapacity()/4 && getCapacity()/2 != 0){//如果队列内容是队列长度的四分之一,缩容 resize(getCapacity()/2); } return ret; } //获得队首值 public E getFront(){ if(isEmpty()){ throw new IllegalArgumentException("Cannot dequeue from an empty queue"); } return data[front]; } private void resize(int newCapacity){ E[] newData = (E[])new Object[newCapacity + 1]; for(int i = 0;i < size;i++){ newData[i] = data[(front+i)%data.length];//data队列的队首在front,循环偏移i } data = newData; front = 0;//在新队列中队首为0 tail = size; } public String toString(){ StringBuilder res = new StringBuilder(); res.append(String.format("Queue: size = %d,capacity = %d\n",size,getCapacity())); res.append("front ["); for(int i = front;i != tail;i =(i+1)%data.length ){ res.append(data[i]); if( (i + 1)%data.length != tail) res.append(","); } res.append("]tail"); return res.toString(); } //测试 public static void main(String []arg) { LoopQueue<Integer> aq = new LoopQueue<>(); for (int i = 0; i < 10; i++) { aq.enqueue(i); System.out.println(aq); if (i % 3 == 2) { aq.dequeue(); System.out.println(aq); } } } }