2

I am trying to implement a CircularArrayQueue. I've been given a JUnit test which my queue must pass.I suppose I am doing something wrong with the front and rear pointers. How should i approach learning data structures and algorithms ?

import java.util.NoSuchElementException;

public class CircularArrayQueue implements MyQueue {
    private Integer[] array;
    // initial size of the array
    private int N;
    private int front;
    private int rear;

    public CircularArrayQueue() {
        this.N = 10;
        array = new Integer[N];
        front = rear = 0;
    }

    public CircularArrayQueue(int size) {
        this.N = size;
        array = new Integer[N];
        front = rear = 0;
    }

    // enqueues an element at the rear of the queue
    // if the queue is already full it is resized, doubling its size
    @Override
    public void enqueue(int in) {
        if (rear == N) {
            if (front == 0) {
                resize();
                array[rear] = in;
                rear++;
            } else {
                array[rear] = in;
                rear = 0;
            }
        } else {
            array[rear] = in;
            rear++;
        }

    }

    public void resize() {
        Integer[] temp = new Integer[array.length * 2];

        for (int i = 0; i < array.length; i++) {
            temp[i] = array[i];
        }

        temp = array;
    }

    // dequeues an element
    // if the queue is empty a NoSuchElement Exception is thrown
    @Override
    public int dequeue() throws NoSuchElementException {
        if (isEmpty()) {
            throw new NoSuchElementException("The queue is full");
        }

        int headElement = array[front];

        if (front == N) {
            array[front] = null;
            front = 0;
        } else {
            array[front] = null;
            front++;
        }

        return headElement;
    }

    @Override
    public int noItems() {
        return N - getCapacityLeft();
    }

    @Override
    public boolean isEmpty() {
        return (getCapacityLeft() == N);
    }

    // return the number of indexes that are empty
    public int getCapacityLeft() {
        return (N - rear + front) % N;
    }
}
5
  • We do not debug your code for you. Hint: at least provide the source for the failing test. Commented Mar 6, 2017 at 8:13
  • I just want feedback on my enqueue and dequeue implementation. There is no problem if it is hard for you. Commented Mar 6, 2017 at 9:24
  • @RadoslavTodorov Well, if its feedback you want, there are a number of problems with your code. Commented Mar 6, 2017 at 9:30
  • 1
    @RadoslavTodorov The % operator comes to our help in writing simple code for data structures like circular queues using arrays. Commented Mar 6, 2017 at 9:33
  • @RadoslavTodorov Feel free for any queries. Commented Mar 6, 2017 at 10:07

1 Answer 1

1

Your initialization is absolutely fine, and we do start with:

front = rear = 0;

Befor adding an item to the Q, we modify rear as

rear = (rear + 1) % N;

The % allows us to maintain the circular property of the queue. Also you must be wondering that if we modify rear before adding any item, then 0 index is left empty, well we have to compromise here with one array item being left blank, in order to have correct implementations for checking of isEmpty() and isFull() functions:

That said, the correct code for isEmpty() is:

@Override
public boolean isEmpty()
{
    return front == rear;
}

You should also have a function isFull() like:

@Override
public boolean isFull()
{
    return front == ((rear + 1) % N);
}

Also the line temp = array; in your resize() should be array = temp; and you must also update the value of N after calling resize().

Hence, the correct code is:

import java.util.NoSuchElementException;

public class CircularArrayQueue implements MyQueue 
{
private Integer[] array;
//initial size of the array
private int N;
private int front;
private int rear;
private int count = 0;//total number of items currently in queue.
public CircularArrayQueue()
{
    this.N = 10;
    array = new Integer[N];
    front = rear = 0;
}

public CircularArrayQueue(int size)
{
    this.N = size;
    array = new Integer[N];
    front = rear = 0;
}


//enqueues an element at the rear of the queue
// if the queue is already full it is resized, doubling its size
@Override
public void enqueue(int in) 
{
    count++;
    if (isFull())
    {
       resize();
       rear = (rear + 1) % N;
       array[rear] = in;
    }
    else
    {
       rear = (rear + 1) % N;
       array[rear] = in;
    }            
}

public void resize()
{
    Integer[] temp = new Integer[array.length*2];
    N = array.length*2;
    for(int i=0; i<array.length; i++)
    {
        temp[i] = array[i];
    }

    array = temp;
}


//dequeues an element
// if the queue is empty a NoSuchElement Exception is thrown
@Override
public int dequeue() throws NoSuchElementException 
{
    if(isEmpty())
    {
        throw new Exception("The queue is empty");
    }

    front = (front + 1) % N;
    int headElement = array[front];   
    count--;
    return headElement;
}

@Override
public int noItems() 
{   
    return count;
}

@Override
public boolean isEmpty()
{
    return front == rear;
}

@Override
public boolean isFull()
{
    return front == ((rear + 1) % N);
}

//return the number of indexes that are empty
public int getCapacityLeft()
{
    return N - 1 - count;
}   
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot. The fact that I am new to programming and my english is pretty bad results in me having a poor understanding of a given concept which is usually the reason I do so many mistakes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.