定义一个Queue的接口
public interface Queue<E> { int getSize(); boolean isEmpty(); void enqueue(E e); E dequeue(); E getFront(); }
引入之前自定义的动态数组Array类
//出队时间复杂度是O(n),其余为O(1) public class ArrayQueue<E> implements Queue<E>{ private Array<E> array; public ArrayQueue(int capacity){ array=new Array<>(capacity); } public ArrayQueue(){ array=new Array<>(); } @Override public int getSize() { return array.getSize(); } @Override public boolean isEmpty(){ return array.isEmpty(); } public int getCapacity(){ return array.getCapacity(); } @Override public void enqueue(E e){ array.addLast(e); } @Override public E dequeue(){ return array.removeFirst(); } @Override public E getFront() { return array.getFirst(); } @Override public String toString(){ StringBuilder res=new StringBuilder(); res.append(String.format("Queue")); res.append("front["); for(int i =0;i<array.getSize();i++){ res.append(array.get(i)); if(i!=array.getSize()-1) res.append(","); } res.append("] tail"); return res.toString(); } }
测试我们实现的数组队列
public static void main(String[] args) { ArrayQueue<Integer> queue = new ArrayQueue<>(); for(int i=0;i<10;i++){ queue.enqueue(i); System.out.println(queue); if(i%3==2){ queue.dequeue(); System.out.println(queue); } } }
结果:
循环队列的实现:
public class LoopQueue<E> implements Queue<E> { private E[] data; private int front, tail; private int size; //循环队列 LoopQueue中不声明size,如何完成所有的逻辑? // 这个问题可能会比大家想象的要难一点点:) //front==tail队列为空,(tail+1)%c==front队列满,capacity中浪费一个空间 public LoopQueue(int capacity){ data = (E[])new Object[capacity + 1]; front = 0; tail = 0; size = 0; } public LoopQueue(){ this(10); } public int getCapacity(){ return data.length - 1; } @Override public boolean isEmpty(){ return front == tail; } @Override public int getSize(){ return size; } @Override public void enqueue(E e){ if((tail+1)%data.length==front) resize(getCapacity()*2); data[tail]=e; tail=(tail+1)%data.length; size++; } @Override 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; } @Override public E getFront(){ if(isEmpty()) throw new IllegalArgumentException("Queue is empty."); 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[(i+front)%data.length]; } data=newData; front=0; tail=size; } @Override 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[] args) { LoopQueue<Integer> queue = new LoopQueue<>(); for(int i=0;i<10;i++){ queue.enqueue(i); System.out.println(queue); if(i%3==2) { queue.dequeue(); System.out.println(queue); } } }
结果: