数组队列和循环队列

定义一个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);
        }
    }
}

结果:


猜你喜欢

转载自blog.csdn.net/qq_25366173/article/details/80299259
今日推荐