队列

队列是先进先出(这里考虑单向队列),队尾进栈,队头出站,当队头指针等于队尾指针时,表示队列里面已经没有元素了,不能再进行出队操作了,当队尾指针等于队列长度时,需要进行扩容(这里并不是需要真正的扩容,下面代码实现的是一种扩容).

public class MyQueue<T> {
    private Object[] t;   //这里声明为Object而不声明为T,是因为下面需要对数组进行实例化,而泛型不能new
    private int capacity = 0; //数组容量,扩容的大小
    private  int popIndex = 0;  //出队指针
    private int pushIndex = 0;  //入队指针

    public MyQueue(){
        this(6); //默认声明数组为6
    }
    public MyQueue(int capacity){
        this.capacity = capacity;
        this.t = new Object[capacity];
    }

    /**
     * 出队,当出队指针大于入队指针时,表示已经没有元素了
     * @return  队列还有元素时返回出队元素,队列没有元素就返回null
     */
    public T pop(){
        if (popIndex < pushIndex){
            T pop = (T)this.t[popIndex]; //需要将Object强转为T
            popIndex ++;  //出队指针+1
            return pop;
        }
        return null;
    }

    /**
     * 入队,当队列还有空位置时,把元素写入队列,没有空元素时(这里指的是入队指针等于数组长度),进行扩容(扩容的改进下面讲)
     * @param push
     */
    public void push(T push){
        if (pushIndex == t.length){
            expansion();
        }
        this.t[pushIndex] =  push; //入队
        pushIndex ++; //入队指针+1
    }
    /**
     * 扩容,上面写的当出队指针(pushIndex)等于数组长度(t.length)就进行扩容是有问题.
     * 现在考虑一个场景,队列长度为6,先入队4个元素,此时popIndex=0,pushIndex = 4,出队4个元素,此时popIndex=3,pushIndex=4
     * 再入队两个元素 popIndex=3,pushIndex=6,如果此时再入队元素,那么队列就会扩容,要是这样一直入队出队,那么就会一直扩容
     * 这就会导致无限制增大,其实队列元素是没有占满的,但是也进行了扩容,这样就会有问题.
     * 改进的方法就是允许进行一次扩容,当出队指针(popIndex)>6(初始容量时),不进行扩容,只进行数组的copy移动.
     */
    private void expansion() {
        int length = popIndex > capacity ? t.length : t.length+capacity;
        Object[] tmp = new Object[length];
        System.arraycopy(t,popIndex,tmp,0,pushIndex-popIndex);
        t = tmp;
        pushIndex = pushIndex-popIndex;
        popIndex = 0;
    }
    public int length(){
        return t.length;
    }

    public int getPopIndex() {
        return popIndex;
    }

    public int getPushIndex() {
        return pushIndex;
    }
}
原文地址:https://www.cnblogs.com/liuzhidao/p/13752147.html