用java以数组为底层结构创建循环队列

本文详细介绍了如何使用Java创建基于数组的循环队列,包括头指针和尾指针的概念、队列满和队列空的判断以及动态扩容和缩容的方法。同时展示了循环队列接口的实现,以支持常见的队列操作。
摘要由CSDN通过智能技术生成

用java以数组为底层结构创建循环队列
循环队列相对于普通队列最大的变化就是添加了一个头指针head,尾指针tail。原先的普通数组队列当入队列再出队列之后,前面就会空出位置,如果要再添加元素的话只能往尾部添加,当添加到容积大小的索引时就会自动扩容往后添加,但永远都不能在前面出队的空出的位置添加,前面的位置就浪费了。循环队列很有效的解决了这一问题,通过两个指针对capacity容积取余来改变指针指向位置从而杜绝上述问题。

尾指针是入队位置的索引,每入队一个元素后,tail++。头指针是出队元素的索引,每出队一个元素后,head++。但是怎么才能循环呢?当尾指针等于capacity时,说明需要改变尾指针到开头位置来插入元素了,tail=(tail+1)%capacity。如果用这样的方法,那队满条件也得改变:(tail+1)%capacity==head。

代码如下:

looparr:底层结构:循环数组

public class LoopArr<T> {
    private T[] value;    //保存数据
    int size;   //实际存放个数
    int capacity;   //容积

    private int head;
    private int tail;

    //  构造方法
    public LoopArr(int capacity){
        //因为队满时要空出来一个位置,所以容积需要相较于之前的普通数组加1
        if(capacity<=0){
            this.capacity=11;
        }else {
            this.capacity=capacity+1;
        }
        this.size=0;
        this.head=this.tail=0;
        this.value=(T[])(new Object[this.capacity]);
        //不可以直接new一个T[]类型,所以需要先new一个Object[]类型然后转为T[]
    }

    //判断数组是否为空
    public boolean IsEmpty(){
        if(this.head==this.tail){
            return true;
        }else{
            return false;
        }
    }

    //向数组中添加元素
    public void add(T data){
        //扩容
        if((this.tail+1)%this.capacity==this.head){   //如果数组满了就重新设置容积
            resize((this.capacity-1)*2+1);  //先把容积变为原先的容积,再×2,加1是循环队列队满时有一个空
        }
        this.value[this.tail]=data;
        //因为是循环的,当队尾指到最后了就需要重新回到第一个位置继续加
        this.tail=(this.tail+1)%this.capacity;
        this.size++;
    }

    //移除队首元素
    public T remove(){
        //缩容
        if(this.size<=this.capacity/4&&this.capacity/2>0){
            resize((this.capacity-1)/2+1);  //与扩容同理
        }
        if(IsEmpty()){
            return null;
        }else{
            T e=this.value[head];
            this.value[head]=null;
            //head指向末尾时需要重新循环到开头,所以如下
            this.head=(this.head+1)%this.capacity;
            this.size--;
            return e;
        }
    }

    //重新给容积
    private void resize(int newcapacity){
        //由于数组的容积都是不变的所以需要新建一个数组
        T [] newvalue=(T[])(new Object[newcapacity]);
        //转移数组
        for (int i = 0; i < this.size; i++) {
            newvalue[i]=this.value[(this.head+i)%this.capacity];    //给新数组赋值,此时capacity还没有变,所以%this.capacity
        }
        //改变容器,数组
        this.value=newvalue;
        this.capacity=newcapacity;
        this.head=0;    //从头开始
        this.tail=this.size;    //尾指针指向最后一个元素的下一个位置也就是size
    }

    public int getHead() {
        return head;
    }

    public int getTail() {
        return tail;
    }

    //获取索引位置的值
    public T getindexdata(int index){
        if(index<0||index>this.capacity){
            throw new IllegalArgumentException("index is invalid.");
        }
        return this.value[index];
    }
    
    //获取实际长度
    public int getSize() {
        return this.size;
    }
    //获取数组的容积
    public int getCapacity() {
        return this.capacity;
    }
}

队列接口:用于被循环队列实现功能

public interface selfqueue<T> {
    //入队
    void offer(T e);

    //出队
    T poll();

    //查看队首元素
    T peak();

    //队列中元素的个数
    int getsize();

    //队列是否为空
    boolean IsEmpty();
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值