欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

数据结构——循环队列

程序员文章站 2022-05-26 12:02:19
...

一、循环队列
数组队列的出队操作的复杂度是O(n),性能很差,解决方法就是使用循环队列(Loop Queue)
在循环队列中,需要对队为空和队为满的时候进行判断,为了区分队空和队满两个条件,需要浪费capacity一个空间,让rear指针一直指向一个空的位置;

当 rear= =front 时,队为空;
当 (rear+1)%n= =front (n为数字角标的最大值)时,队为满.

示意图如下:
数据结构——循环队列循环队列实现:

//循环队列
public class ArrayQueueLoop<E> implements Queue<E> {
    private E[] data;
    private int front;
    private int rear;
    private int size;
//无参构造函数
    public ArrayQueueLoop(){
        data= (E[]) (new Object[11]);//因为有一个空的空间
        front=0;
        rear=0;
        size=0;
    }
//获取长度
    @Override
    public int getSize() {
        return size;
    }
//判空
    @Override
    public boolean isEmpty() {
        return size==0&&front==rear;
    }
//进队
    @Override
    public void enqueue(E e) {
        if((rear+1)%data.length==front){
            resize(2*data.length-1);
        }
        data[rear]=e;
        rear=(rear+1)%data.length;
        size++;
    }
//出队
    @Override
    public E dequeue() {
        if(isEmpty()){
            throw new IllegalArgumentException("队列空");
        }
        E ret=data[front];
        front=(front+1)%data.length;
        size--;

        if(size<=(data.length-1)/4&&(data.length-1)/2>=10){
            resize((data.length-1)/2+1);
        }

        return ret;
    }
//改变数组长度    
    private void resize(int newLen){
        E[] newData= (E[]) (new Object[newLen]);
        int p=front;
        int i=0;
        while(true){
            newData[i]=data[p];
            i++;
            p=(p+1)%data.length;
            if(p==rear){
                break;
            }
        }
        front=0;
        rear=size;
        data=newData;
    }
//获取队头元素
    @Override
    public E getFront() {
        if(isEmpty()){
            throw new IllegalArgumentException("队列为空");
        }
        return data[front];
    }
//获取队尾元素
    @Override
    public E getRear() {
        if(isEmpty()){
            throw new IllegalArgumentException("队列为空");
        }
        return data[(rear-1+data.length)%data.length];
    }
//清空队列
    @Override
    public void clear() {
        data= (E[]) (new Object[11]);//因为有一个空的空间
        front=0;
        rear=0;
        size=0;
    }
//自定义格式打印元素
    @Override
    public String toString() {
        StringBuilder sb=new StringBuilder();
        sb.append(String.format("ArrayQueueLoop: %d/%d\n",size,data.length-1));
        sb.append('[');
        if(isEmpty()){
            sb.append(']');
        }else{
            for(int i=front;i!=rear;i=(i+1)%data.length){
                sb.append(data[i]);
                if((i+1)%data.length==rear){
                    sb.append(']');
                }else{
                    sb.append(',');
                }
            }
        }
        return sb.toString();
    }
}