java数组实现环形队列

总结一下:

一个环形队列中,有如下元素:

属性:

  1. 队列最大长度 ———maxSize
  2. 队列头———front
  3. 队列尾———rear
  4.  存放队列的数组———arr[]

方法:

  1. 队列构造函数———public CirclrQueue(int _maxSize)
  2. 判断队列为空的方法———public void isEmpty()
  3. 判断队列为满的方法———public void isFull()
  4. 返回队列最大长度的方法———public int validLength()
  5. 往队列里添加数据方法———public void addQueue()
  6. 取出队列数据方法———public int getQueue()
  7. 返回队列头方法———public int headQueue()   (注意,只是返回队列头的副本,队列不改变)
  8. 展示队列方法———public void show()

废话不多说,直接上代码

public class CircleQueue {

    int maxSize;//队列最大长度
    int rear;//指向队列最后一个元素的后一个,这里希望预留一个空间,即rear指向的空间是不存数据的,但front指向的空间存了数据
            //预留一个空间的原因是为了防止为空和为满的判定重复
    int front;//指向队列的第一个元素
    int [] arr ;
    public CircleQueue(int _maxSize){
        maxSize = _maxSize;
        rear = 0;
        front = 0;
        arr = new int [maxSize];

    }
    public boolean isFull(){
        return (rear + 1 )% maxSize == front;
        /*
        这里为什么要取模呢?
        首先如果rear不是在队列的末尾时,其实是不需要取模的,
        因为直接有rear + 1 == front可以判定队列为满
        但如果当rear处于队列的末尾时,即rear = maxSize - 1,front = 0时,这里(rear + 1) % maxSize = 0 = front
        这样就可以判定队列满
        另外我们这里的队列满的定义是指队列中存了maxSize - 1个数据,而不是maxSize个数据,因为rear指向的空间并没有存入数据
         */
    }

    public boolean isEmpty(){
        return rear == front;
        /*
        首先确定队列是怎么为空的
        1.队列一开始就为空,没有存入数据,此时就有rear == front 判断队列为空,因为rear和front初始化都为0
        2.数据一直出队列,即front一直向后移,当front指向rear前面一个位置时,即front = rear - 1
         此时队列还是存在数据的,因为front指向的空间还存了一个数据
        这是我们一开始就定义好的,rear指向的空间不存数据,front指向的空间存数据,之后front再后移,此时front = rear,
        并且front指向的指向的最后一个数据出队列,此时队列无数据,队列为空
         */

    }


    public int validLength(){
        return (rear + maxSize -front) % maxSize;
        /*
        这里的方法返回队列的有效长度
        虽然式子看起来挺长的,但让我们来分情况来看(注意:我们这里是环形队列,所以有可能出现rear在front前面的情况)
        1.当front在rear前面(也就是普通的情况)
        此时队列的有效长度其实就可以用rear - front 表示,但上述的式子也可以表示,之所以用上述式子是因为另一种情况
        2.当front在rear后面
        这里的rear - front就为负数了,并且它的绝对值表示的也不是队列的有效长度,而是队列的中未存入数据的长度
        即 未存入数据的长度 = |rear - front| = front - rear
        而我们又有  有效长度 + 未存入数据的长度 = maxSize(因为队列中所有的数据只可能有这两种情况)
        所以在这种情况下,有效长度 = maxSize - 未存入数据的长度 = maxSize + rear - front = rear + maxSize - front
        这与我们的式子形式上非常相似了,还有最后一个问题,为什么要取模?
        注意,这是front在rear后面时的情况,rear + maxSize - front 这个式子对第一种情况并不适用
        所以我们取模使其能够以一个统一的形式写成


        ps:
        其实写这么多没什么用(-_-''),不妨用代码写出,如下:
        if(rear - front >= 0){
        return rear -front;
        }
        else {
        return rear + maxSize - front
        }
         */

    }
    public void addQueue(int data){
        if(isFull()){
            System.out.println("队列已满,无法添加数据");
            return;
        }
        else {
            arr[rear] = data;
            rear = (rear + 1) % maxSize;
            return;
        }



    }

    public int getQueue(){

        if(isEmpty()){
            throw new RuntimeException("队列空,无法取出数据");
        }
        else {
            int value;
            value = arr[front];
            front = (front + 1) % maxSize;
            return value;
        }



    }
    public void show(){
        if(isEmpty()){
            System.out.println("队列为空,没有数据");
        }
        else{
            //这里不从0遍历到队列末尾,因为这样不知道队列头是什么,所以我们从队列头遍历完有效数据
            for (int i = front; i <front + validLength() ; i ++){
                System.out.printf("arr[%d] = %d\n",i % maxSize,arr[i % maxSize]);

            }

        }
    }

    public int headQueue(){
        if(isEmpty()){
            throw new RuntimeException("队列空,无head");
        }
        else{
            return arr[ front ];
        }
    }




}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值