回顾数据结构---循环队列

   循环队列。顾明四姨~就像围成一个圈,有两个标记,一个头一个尾,从头出去从尾插入

定义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);
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值