JAVA数组实现环形队列(下篇)

关于上一篇文章,测试了代码发现所实现的队列只能使用一次。、
是一个问题很大的数据结构。
所以
为了能够让队列变得优化,对上一篇的代码进行了修改。

关于上一篇队列的实现,只能使用一次的原因也说过了。
这里再简单说一下:

如果我们在队列里面添加满元素后:
在这里插入图片描述
rear指向最后一个数组元素的位置。这个时候队列满了。
然后我们再出队出队一直出。
在这里插入图片描述

即便最后一个元素也出队了,但是里面的元素并没有删除,只是front++到了rear的位置,因为二者相等,所以起到了一个队列为空的效果。

但也正是因为这样。我们这个队列才只能够使用一次。
那我们有没有什么改进的方法呢?

在这里插入图片描述
如图所示,如果我们rear已经到最后了的时候,而且已经有出队的元素了(说明下面有位置占着没有用的元素),再让rear++的时候,我们让rear指向第一个元素,从而覆盖之前的元素,这样不就形成了一个环。然后front也是同理,当出队到最后一个的时候,就让他从0接过去。是不是就起到了环形队列的效果,这样队列就不仅仅是只能使用一次了。

有了思路的话,我们就可以开始写代码了。
首先的过程都一样,新建类,写成员变量和构造函数。

  private int maxSize;
    private int rear;
    private int front;
    private int arr[];

    public ArrayCircleQueue(int size){
        this.maxSize=size+1;
        this.arr=new int[maxSize];
    }

这次我们让rear和front都指向第一个元素,先赋值再++。
所以这里我们要非常注意的是!!!!!!!!!!!!
我们的rear和front初始值已经不是-1了。
是从0开始的。
所以我们如果给初始容量设置为5的话,那么队列的有效值应该为5-1=4.

这里要重点注意一下

然后我们来写判断队列是否已满的方法。
第一种情况:
在这里插入图片描述
此时front没动,为0.
rear++后为就会为4;不能再增加了。

第二种情况:
在这里插入图片描述
此时front移动了一下,为1。
rear从上面下来了,为0.

现在我也只能总结出一个公式来表示已满的情况。
但也没有数学能力证明出这个公式,只能够凭借学习和经验获取。

    public boolean isImpty(){
        return (rear+1) % maxSize== front;
    }

这就是一个判断是否满了的方法,可以尝试一下。
然后判断是否为空的话和上一篇说的是一样的:

    public boolean isNull(){
        return front == rear;
    }

那有了这两种方法之后呢,我们就可以写入队和出队的方法了。

入队方法,先判断一下是否已满。
然后进行入队。

    public void push(int data){
        if(isImpty()){
            System.out.println("队列已满,无法入队");
            return;
        }
        arr[rear]=data;
        System.out.println(arr[rear]+"入队成功");
        rear=(rear+1) % maxSize;
    }

这里就不能让rear++了。
要不然rear就没有办法从上面过度到下面而是索引越界了。

出队的方法如出一辙。

    public  void pop(){
        if(isNull()){
            System.out.println("队列为空,无法出队");
            return;
        }
        System.out.println(arr[front]+"已经出队");
        front=(front+1) % maxSize;
    }

OK,最后再把总的代码一起整理一下:

package ArrayQueue;

public class ArrayCircleQueue {
    private int maxSize;
    private int rear;
    private int front;
    private int arr[];

    public ArrayCircleQueue(int size){
        this.maxSize=size+1;
        this.arr=new int[maxSize];
    }

    public boolean isNull(){
        return front == rear;
    }

    public boolean isImpty(){
        return (rear+1) % maxSize== front;
    }

    public void push(int data){
        if(isImpty()){
            System.out.println("队列已满,无法入队");
            return;
        }
        arr[rear]=data;
        System.out.println(arr[rear]+"入队成功");
        rear=(rear+1) % maxSize;
    }

    public  void pop(){
        if(isNull()){
            System.out.println("队列为空,无法出队");
            return;
        }
        System.out.println(arr[front]+"已经出队");
        front=(front+1) % maxSize;
    }
}

然后我们用测试函数来测试一下:

    public static void main(String[] args) {
        ArrayCircleQueue arrayCircleQueue= new ArrayCircleQueue(5);

        for(int i=0;i<5;i++){
            arrayCircleQueue.push(i);
        }
        arrayCircleQueue.push(1);
        //出队
        for (int i=0;i<5;i++){
            arrayCircleQueue.pop();
        }
        arrayCircleQueue.pop();
        arrayCircleQueue.push(1);
        arrayCircleQueue.pop();
    }

让我们来看一下效果:
0入队成功
1入队成功
2入队成功
3入队成功
4入队成功
队列已满,无法入队
0已经出队
1已经出队
2已经出队
3已经出队
4已经出队
队列为空,无法出队
1入队成功
1已经出队

这样的话队列就不是只能使用一次了!

OK,关于数组实现队列,通过两篇文章也是说完了。
END。

©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页