My queue fails to display when I remove then add an item - java

I modified a program which creates a Queue and then add or remove items to it.
The problem in my code is that after I remove one item, and then add an item it goes into infinite loop and I'm not sure how to prevent it from happening.
My goal is to modify display() method only.
This is how I display Queue:
public void display()
{
int i = front;
do {
if (maxSize == nItems)
{
if (i == size())
i = 0;
System.out.print(queArray[i++] + " ");
}
else if (maxSize < nItems)
{
System.out.print("Too many queue items!");
break;
}
else
maxSize = nItems;
}
while (i != rear + 1 && !isEmpty());
}
This is how I add and remove items:
public void insert(long j) // put item at rear of queue
{
if(rear == maxSize-1) // deal with wraparound
rear = -1;
queArray[++rear] = j; // increment rear and insert
nItems++; // one more item
}
public long remove() // take item from front of queue
{
long temp = queArray[front++]; // get value and incr front
if(front == maxSize) // deal with wraparound
front = 0;
nItems--; // one less item
return temp;
}

Here is the source code for the same.
import java.util.Arrays;
public class Queue {
private int enqueueIndex;// Separate index to ensure enqueue happens at the end
private int dequeueIndex;// Separate index to ensure dequeue happens at the
// start
private int[] items;
private int count;
// Lazy to add javadocs please provide
public Queue(int size) {
enqueueIndex = 0;
dequeueIndex = 0;
items = new int[size];
}
// Lazy to add javadocs please provide
public void enqueue(int newNumber) {
if (count == items.length)
throw new IllegalStateException();
items[enqueueIndex] = newNumber;
enqueueIndex = ++enqueueIndex == items.length ? 0 : enqueueIndex;
++count;
}
// Lazy to add javadocs please provide
public int dequeue() {
if (count == 0)
throw new IllegalStateException();
int item = items[dequeueIndex];
items[dequeueIndex] = 0;
dequeueIndex = ++dequeueIndex == items.length ? 0 : dequeueIndex;
--count;
return item;
}
#Override
public String toString() {
return Arrays.toString(items);
}
}

Related

How is this java code is deleting an item from a list without using .remove()?

I'm reading an algorithms textbook and I came across this line from a code example:
long temp = queArray[front++];
I understand what the front++ is doing and what item it is accessing, but this seems to be also deleting the item from the array. I don't understand how it is doing that.
In case I missed something, here is the rest of the method:
public long remove() { // take item from front of queue
long temp = queArray[front++]; // get value and incr front
if(front == maxSize) // deal with wraparound
front = 0;
nItems--; // one less item
return temp;
}
Additionally, here is the rest of the class:
class Queue
{
private int maxSize;
private long[] queArray;
private int front;
private int rear;
private int nItems;
public Queue(int s) // constructor
{
maxSize = s;
queArray = new long[maxSize];
front = 0;
rear = -1;
nItems = 0;
}
public void insert(long j) // put item at rear of queue
{
if(rear == maxSize-1) // deal with wraparound
rear = -1;
queArray[++rear] = j; // increment rear and insert
nItems++; // one more item
}
public long remove() // take item from front of queue
{
long temp = queArray[front++]; // get value and incr front
if(front == maxSize) // deal with wraparound
front = 0;
nItems--; // one less item
return temp;
}
public long peekFront() // peek at front of queue
{
return queArray[front];
}
public boolean isEmpty() // true if queue is empty
{
return (nItems==0);
}
public boolean isFull() // true if queue is full
{
return (nItems==maxSize);
}
public int size() // number of items in queue
{
return nItems;
}
} // end class Queue

CircularArrayQueue implementation Java

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;
}
}
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;
}
}

Where is the memory leak in the remove method?

Where is the possible memory leak in my code? There is also supposed to be a programming error too in one the methods as well, that might cause problems if I create a subclass of this class.
The add method basically just takes an index of where to add the item. For every item that occupies anything after the index in the current array, it just copies it over a spot over, and then places the item into index. I don't see what's wrong with it.
For the remove method, it does the same thing basically, except in reverse.
private static final int MAX_LIST = 3;
protected Object []items;
protected int numItems;
public MyArray()
{
items = new Object[MAX_LIST];
numItems = 0;
}
/*the programming error should be in this method*/
public void add(int index, Object item)
throws ListIndexOutOfBoundsException
{
if (numItems > items.length)
{
throw new ListException("ListException on add");
}
if (index >= 0 && index <= numItems)
{
for (int pos = numItems-1; pos >= index; pos--)
{
items[pos+1] = items[pos];
}
items[index] = item;
numItems++;
}
else
{
throw new ListIndexOutOfBoundsException(
"ListIndexOutOfBoundsException on add");
}
}
/*The memory leak should be in this method*/
public void remove(int index)
throws ListIndexOutOfBoundsException
{
if (index >= 0 && index < numItems)
{
for (int pos = index+1; pos < numItems; pos++)
{
items[pos-1] = items[pos];
}
numItems--;
}
else
{
throw new ListIndexOutOfBoundsException(
"ListIndexOutOfBoundsException on remove");
}
}
Make sure that unused items elements are set to null otherwise objects referenced from there cannot be garbage collected.
After the for loop shifting down the items add a line:
items[numItems-1] = null;

Queue array implementation resize

I was required to create a simple queue array implementation with basic methods as enqueue, dequeue, isEmpty, and stuff like that. My only problem is that Im stuck when it comes to the resize method, because if I want to add more values to my queue (with fixed size because is an array) I do not know how to make it work and keep all the values in place.
Everything works just in case you were wondering, the only thing is that doesnt work is my resize (the method wrote in here wasn't the only one I tried).
I'm going to put my main method as well if you want to try it, hope you can help, thanks.
Main Method:
public class MainQueue {
public static void main(String[] args) {
int capacity=10;
Queue<Integer> queue = new Queue<Integer>(capacity);
queue.enqueue(1);
queue.enqueue(2);
queue.enqueue(3);
queue.enqueue(4);
queue.enqueue(5);
queue.enqueue(6);
queue.enqueue(7);
queue.enqueue(8);
queue.enqueue(9);
queue.enqueue(10);
System.out.println("Queue: "+ queue);
//WORKS SO FAR
queue.enqueue(11);
//11 is placed at the beginning of the queue
//instead at the end and my last value is null (?)
Class queue:
import java.util.NoSuchElementException;
public class Queue <E>{
private E[] elements;//array in generic
private int front;//first element or front of the queue
private int back;//last element or back of the queue
private int capacity; //capacity of the queue
private int count; //indicates number of elements currently stored in the queue
#SuppressWarnings("unchecked")
public Queue(int size)
{
capacity = size;
count = 0;
back = size-1;
front = 0;
elements =(E []) new Object[size]; //array empty
}
//Returns true if the queue is empty or false
public boolean isEmpty()
{
return count==0;//means its true
}
//Add elements to the queue
public void enqueue(E item)
{
if(count == capacity)
{
resize(capacity*2);
// System.out.println("Queue is full");
}
back =(back+1) % capacity; //example back=(0+1)%10=1
elements[back]=item;
//elements[0]=0
//item=elements[count];
count++;
}
//Public resize
public void resize(int reSize){
E[] tmp = (E[]) new Object[reSize];
int current = front;
for (int i = 0; i < count; i++)
{
tmp[i] = elements[current];
current = (current + 1) % count;
}
elements = tmp;
}
//Dequeue method to remove head
public E dequeue()
{
if(isEmpty())
throw new NoSuchElementException("Dequeue: Queue is empty");
else
{
count--;
for(int x = 1; x <= count; x++)
{
elements[x-1] = elements[x];
}
capacity--;
return (E) elements;
}
}
//peek the first element
public E peek()
{
if(isEmpty())
{
throw new NoSuchElementException("Peek: Queue is empty");
}
else
return elements[front];
}
//Print queue as string
public String toString()
{
if(isEmpty()) {
System.out.println("Queue is empty.");
//throw new NoSuchElementException("Queue is empty");
}
String s = "[";
for(int i = 0; i <count; i++)
{
if(i != 0)
s += ", ";
s = s + elements[i];// [value1,value2,....]
}
s +="]";
return s;
}
public void delete() { //Delete everything
count = 0;
}
}
you forgot to update stuff when resizing:
front, capacity and back .
public void resize(int reSize){
E[] tmp = (E[]) new Object[reSize];
int current = front;
for (int i = 0; i < count; i++)
{
tmp[i] = elements[current];
current = (current + 1) % count;
}
elements = tmp;
front = 0;
back = count-1;
capacity=reSize;
}
You have few mistakes in resizing when enqueing item which expand queue.
in resize algorithm
current = (current + 1) % count; should be (current + 1) % capacity
You have to change capacity value in resize function
capacity = resize;
Why are you changing capacity when dequeing?

Circular Queue java not printing right

hey guys i have a problem when trying to print out the circular queue array
heres my code:
public class CircularQueue {
private int [] queue;
private int front, rear;
// do not change the constructor
CircularQueue() {
queue = new int [5];
front = 0;
rear = -1;
}
// FILL IN:
// throws DSException if out of space
public void enqueue ( int item ) throws DSException {
if ( front == 0 && rear == -1 ){
throw new DSException();
}
queue[rear+1] = item;
rear = (rear+1)%queue.length;
}
// FILL IN:
// throws DSException if no element in the queue
// return the dequeued value
public int dequeue () throws DSException {
if ( front == 0 && rear == -1 ){
throw new DSException();
}
int temp = queue[front];
queue[front] = 0;
front = (front+1)%queue.length;
return temp;
}
// FILL IN:
// return the value at beginning of the queue
// throws DSException if no element in the queue
public int first () throws DSException {
return front;
}
// FILL IN:
// print the circular queue in the following format
// - print "+" before the value at the front
// - print "-" after the value at the rear
// - print "." for the places without valid element.
public void print () {
System.out.print(" <");
for ( int i = 0; i < queue.length; i++ ){
if ( front == 0 && rear == -1 ){
System.out.print("."+"\t");
} else if ( i == front ) {
System.out.print("+"+ queue[i]);
} else if ( i == rear ) {
System.out.print( queue[i]+ "-");
} else if ( i == front && i == rear) {
System.out.print("+"+ queue[i] +"-");
} else {
System.out.print( queue[i] );
}
}
System.out.print(">\n");
}
}
and here's the result
EMPTY:
<. . . . . >
ENQUEUE (0):
i am supposed to enqueue 0-4 and dequeue some element but it stops after enqueue 0.
A CircularQueue can be in 3 states whose invariants are given below :
Empty : front == -1 && rear == -1
Full : (rear+1)%queue.length == front
Neither empty nor full : Does not satisfy the conditions mentioned above
public class CircularQueue {
private int [] queue;
private int front, rear;
// do not change the constructor
CircularQueue() {
queue = new int [5];
front = -1;
rear = -1;
}
// FILL IN:
// throws DSException if out of space
public void enqueue ( int item ) throws DSException,Exception {
if ( front == -1 && rear == -1 ){
front = 0;
rear = 0;
queue[rear] = item;
}
else if((rear+1)%queue.length == front) {
throw new Exception("Full");
}
else {
rear = (rear+1)%queue.length;
queue[rear] = item;
}
}
// FILL IN:
// throws DSException if no element in the queue
// return the dequeued value
public int dequeue () throws DSException {
if ( front == -1 && rear == -1 ){
throw new DSException();
}
else {
int ret = queue[front];
if(rear==front) {
rear = -1;
front = -1;
}
else {
front = (front+1)%queue.length;
}
return ret;
}
}
// FILL IN:
// return the value at beginning of the queue
// throws DSException if no element in the queue
public int first () throws DSException {
if(front==-1 && rear ==-1) {
throw new DSException();
}
return queue[front];
}
// FILL IN:
// print the circular queue in the following format
// - print "+" before the value at the front
// - print "-" after the value at the rear
// - print "." for the places without valid element.
public void print () {
if(front==-1 && rear == -1) {
for(int i=0;i<queue.length;i++) {
System.out.print(".");
}
}
else {
if(front<=rear) {
for(int i=0;i<=front-1;i++) {
System.out.print(".");
}
System.out.print("+");
for(int i=front;i<=rear;i++) {
System.out.print(queue[i]);
}
System.out.print("-");
for(int i=rear+1;i<=queue.length-1;i++) {
System.out.print(".");
}
}
else {
for(int i=0;i<=rear;i++) {
System.out.print(queue[i]);
}
System.out.print("-");
for(int i=rear+1;i<=front-1;i++) {
System.out.print(".");
}
System.out.print("+");
for(int i=front;i<=queue.length-1;i++) {
System.out.print(queue[i]);
}
}
}
}
}
This is my approach. But I am assuming here that the empty blocks in the array are initialized with zero, and that any valid entry would be non-zero. Also, it will print zeros in case the queue is partially filled.
public void print() {
if (isEmpty()) {
System.out.println("Queue is empty");
} else {
System.out.println("In order from latest to oldest");
int i = front;
while (i < array.length) {
System.out.print(array[i] + " ");
i++;
}
i = i % array.length;
if(array[i] != 0) {
while(i < front) {
System.out.print(array[i] + " ");
i++;
}
}
}
}
Problem with circular arrays and front/rear indices is that 'full' and 'empty' are indistinguishable. You will have to add a boolean 'empty', which is initially true, and is used in the tests.
private int [] queue;
private int front, rear;
private boolean empty;
// do not change the constructor
CircularQueue() {
queue = new int [5];
front = 0;
rear = -1;
empty = true;
}
// FILL IN:
// throws DSException if out of space
public void enqueue ( int item ) throws DSException {
if (!empty && (front - rear + queue.length) % queue.length == 1){
throw new DSException();
}
queue[rear+1] = item;
rear = (rear+1)%queue.length;
empty = false;
}
// FILL IN:
// throws DSException if no element in the queue
// return the dequeued value
public int dequeue () throws DSException {
if (empty){
throw new DSException();
}
int temp = queue[front];
queue[front] = 0;
front = (front+1)%queue.length;
empty = (front - rear + queue.length) % queue.length == 1;
return temp;
}

Categories

Resources