手动设计实现循环队列

队列和循环队列

循环队列相对于队列特点在于出队时队内元素不用依次移位,多维护了两个变量front和tail,front指向队首而tail指向队尾元素。

循环队列图示操作

  • 循环队列为空的情况
    front==tail
    在这里插入图片描述
  • 循环队列入队操作
    每添加一个元素,tail往后挪一个位置
    在这里插入图片描述
    下图会告诉你为什么叫循环队列
    在这里插入图片描述
  • 循环队出队操作
    删除一个元素,更新front对应的索引,注意这里不需要将后面的元素往前依次挪位
    出队操作
    -循环列队满元素状态
    如果再添加元素会front=tail,而这是循环队列为空的条件
    (tail+1)%array.length==front
    在这里插入图片描述

循环队列java代码实现

现在一起来实现一下循环队列吧!
循环队列的基本操作有:

  • 入队方法
    void enqueue(E element)

  • 出队方法并返回出队的元素
    E dequeue()

  • 为空判断
    boolean isEmpty()

  • 返回循环队列中的元素个数
    int getSize()

  • 返回循环队列的容量
    int getCapacity()

  • 返回循环队列队首元素
    getFront()

public class LoopQueue<E> {
    private E[] data;
    private int front;
    private int tail;
    private int size;

    public LoopQueue(int capacity){
//        因为浪费了一个空间,所以要在用户以为的容量上加上1
        data=(E[])new Object[capacity+1];
        front=0;
        tail=0;
        size=0;

    }

    public LoopQueue() {
        this(10);
    }

    //    入队操作
    public void enqueue(E element){
//        添加操作前对循环队列是否满进行判断
        if((tail+1)%data.length==front){
            resize(getCapacity()*2);
        }
        data[tail]=element;
        tail=(tail+1)%data.length;
        size++;
    }

    //    出队操作
    public E dequeue(){
        if(isEmpty()){
            throw new IllegalArgumentException("不能对空队列进行出队操作");
        }
//        rem=remain
        E rem=data[front];
        //对象数组存储的是引用,这一步操作不至于使存储的引用所指向的对象一直占用空间
        data[front]=null;
        front=(front+1)%data.length;
        size--;
        if(size==getCapacity()/4 && getCapacity()/2!=0){
            resize(getCapacity()/2);
        }
        return rem;
    }


    private void resize(int newcapacity) {
//        扩容操作,在新的数组中令front元素移至index=0的位置
        E[] newData=(E[])new Object[newcapacity+1];
//        两种方式遍历循环队列之一,i<size,而不是getCapacity
        for (int i = 0; i < size; i++) {
            newData[i]=data[(i+front)%data.length];
        }
        front=0;
        tail=size;
        data=newData;

    }

    public boolean isEmpty(){
        return front==tail;
    }

    
    public int getSize(){
        return size;
    }


    public int getCapacity(){
        return data.length-1;
    }


    public E getFront(){
        if(isEmpty()){
            throw new IllegalArgumentException("队列是空的");
        }
        return data[front];
    }

    @Override
    public String toString(){
        StringBuilder buffer=new StringBuilder();
//        String.format格式化的字符串
        buffer.append(String.format("Queue:size=%d ,capacity=%d\n",size,getCapacity()));
        buffer.append("front [");
//        两种方式遍历循环队列之二
        for (int i = front; i!=tail ; i=(i+1)%data.length) {
            buffer.append(data[i]);
            if((i+1)!=tail){
                buffer.append(", ");
            }

        }
        buffer.append("] tail");
        return buffer.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);
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值