front = (front + 1) % data.length执行出错

来源:3-8 数组队列和循环队列的比较

流l殇

2019-02-28

在leetcode的编写循环队列问题中编写出队函数:

class MyCircularQueue {


    int[] data;

    int front;

    int tail;

    int size;


    /** Initialize your data structure here. Set the size of the queue to be k. */

    public MyCircularQueue(int k) {


        data = new int[k + 1];

        front = 0;

        tail = 0;

        size = 0;

    }


    /** Insert an element into the circular queue. Return true if the operation is successful. */

    public boolean enQueue(int value) {


        if(isFull()){

            return false;

        }


        data[tail] = value;

        tail = (tail + 1) % data.length;

        size ++;

        return true;

    }


    /** Delete an element from the circular queue. Return true if the operation is successful. */

    public boolean deQueue() {


        if(isEmpty()){

            return false;

        }


        front = (front + 1) % data.length;

        size --;

        return true;


    }


    /** Get the front item from the queue. */

    public int Front() {


        if(isEmpty()){

            return -1;

        }

        return data[front];

    }


    /** Get the last item from the queue. */

    public int Rear() {


        // if(isEmpty()){

        //     return -1;

        // }

        // if(tail - 1 < 0){

        //     return data[data.length - 1];

        // }

        // else{

        //     return data[tail - 1];

        // }

        

        return data[(tail - 1) % data.length];

    }


    /** Checks whether the circular queue is empty or not. */

    public boolean isEmpty() {


        return front == tail;

    }


    /** Checks whether the circular queue is full or not. */

    public boolean isFull() {


        return (tail + 1) % data.length == front;

    }


    public static void main(String[] args){

        MyCircularQueue obj = new MyCircularQueue(6);

        boolean param_1 = obj.enQueue(6);

        int param_2 = obj.Rear();

        int param_3 = obj.Rear();

        boolean param_4 = obj.deQueue();

        boolean param_5 = obj.enQueue(5);

        int param_6 = obj.Rear();

        boolean param_7 = obj.deQueue();

        int param_8 = obj.Front();

        boolean param_9 = obj.deQueue();

        boolean param_10 = obj.deQueue();

        boolean param_11 = obj.deQueue();


        System.out.println(param_1);

        System.out.println(param_2);

        System.out.println(param_3);

        System.out.println(param_4);

        System.out.println(param_5);

        System.out.println(param_6);

        System.out.println(param_7);

        System.out.println(param_8);

        System.out.println(param_9);

        System.out.println(param_10);

        System.out.println(param_11);

    }

}


/**

 * Your MyCircularQueue object will be instantiated and called as such:

 * MyCircularQueue obj = new MyCircularQueue(k);

 * boolean param_1 = obj.enQueue(value);

 * boolean param_2 = obj.deQueue();

 * int param_3 = obj.Front();

 * int param_4 = obj.Rear();

 * boolean param_5 = obj.isEmpty();

 * boolean param_6 = obj.isFull();

 */

提交时front = (front + 1) % data.length;这句话总是提示执行出错是什么情况

写回答

2回答

liuyubobobo

2019-03-01

你的所有问题使用这个测试用例都能展现出来(就是Leetcode这个问题的默认测试用例。)

public static void main(String[] args){
    MyCircularQueue q = new MyCircularQueue(3);
    for(int i = 1; i <= 3; i ++){
        q.enQueue(i);
    }
    System.out.println(q.Rear());
    System.out.println(q.deQueue()); // 1
    q.enQueue(4); // 2
    System.out.println(q.Rear());
}


现在这个代码的问题是,当tail==0的时候,Rear函数中(tail - 1) 是负数,所以给data的索引是负数,数组越界。


这个代码,将你说的front = (front + 1) % data.length;一行去掉以后,在deQueue之后,front没有得到正确的维护。front本来应该在后面,现在还在原来的位置。这就会在注释//1 之后,本来腾出了一个位置,却被错误的认为当前队列为满(但其实没满,因为front是错的),所以// 2 的这个4根本就没有enQueue进去,tail也不会变为0,就不会触发上面的索引越界。


这个用例的队列只能容纳三个元素,足够小了。使用debug,自己一步一步跟踪一下,再仔细理解一下问题出在哪里?


加油!

1
1
流l殇
好的,明白了,谢谢
2019-03-01
共1条回复

liuyubobobo

2019-03-01

具体是哪个问题,提示出什么错?你的完整代码是怎样的?

0
4
流l殇
回复
liuyubobobo
题号为622,有问题的完整代码放到修改后的问题描述了,问题应该是出在Rear函数的return语句,但是如果注释掉deQueue中front = (front + 1) % data.length; 就会执行但是不会报错
2019-03-01
共4条回复

玩转数据结构

动态数组/栈/队列/链表/BST/堆/线段树/Trie/并查集/AVL/红黑树…

6221 学习 · 1704 问题

查看课程