implementing queue with arrays - java

im very confused as to why my queue is not working, i believe that there is a problem in the enqueue and dequeue methods. but im not sure, i am supposed to Implement the class with the initial array size set to 8. The array size will be doubled once the number of the elements exceeds the size. After an element is removed from the beginning of the array, you need to shift all elements in the array one position the left. Write a test program that adds 20 numbers from 1 to 20 into the queue and removes these numbers and displays them. here is my code
public class Queue {
private int[] elements;
private int size;
private int first;
private int last;
public static final int DEFAULT_CAPACITY = 8;
public Queue(){
this (DEFAULT_CAPACITY);
}
public Queue (int capacity){
elements = new int[capacity];
first = 0;
last = 0;
size = 8;
}
public void Enqueue(int v){ //fills queue and lengthens if necessary
if (last>=size){
int[] temp = new int[elements.length*2];
System.arraycopy(elements, 0, temp, 0, elements.length);
elements = temp;
}
elements[last]=v;
last++;
}
public int Dequeue(){
int output = elements[first];
System.out.print(output + " ");
while(last != 0){
for(int i = 0; i<last;i++){
elements[i]= elements[i-1];
}
last--;
}
return output ;
}
public boolean empty(){ // tests for empty queue
return last==first;
}
public int getSize(){
size=last;
return size;
}
}
and here is the tester class.
public class QueueTester {
public static void main(String[] args){
Queue q = new Queue();
q.Enqueue(1);
q.Enqueue(2);
q.Enqueue(3);
q.Enqueue(4);
q.Enqueue(5);
q.Enqueue(6);
q.Enqueue(7);
q.Enqueue(8);
q.Enqueue(9);
q.Enqueue(10);
q.Enqueue(11);
q.Enqueue(12);
q.Enqueue(13);
q.Enqueue(14);
q.Enqueue(15);
q.Enqueue(16);
q.Enqueue(17);
q.Enqueue(18);
q.Enqueue(19);
q.Enqueue(20);
while (q.empty()){
q.Dequeue();

while(last != 0){
for(int i = 0; i<last;i++){
elements[i]= elements[i-1];
}
last--;
}
Remove the while loop. If you're trying to make sure it's not dequeueing an empty queue have an if condition check to ensure that the size is > 0.
public int Dequeue(){
if (getSize() == 0) {
// throw an error or something
}
int output = elements[first];
System.out.print(output + " ");
for(int i = 0; i<last;i++){
elements[i]= elements[i-1];
}
last--;
return output ;
}
Additionally you need to print the output in your tester class, and I assume you want to dequeue while the queue is NOT empty:
while (!q.empty()){
System.out.println(q.Dequeue());

Mmm, think the algorithm you are using is not correct try referring this http://projectyogisha.com/implementing-queues/ , its in C though.

Related

Why won't my recursive function recurse through all of the data in the stack?

I am trying to reverse a stack of type int using recursion. I am able to reverse the first entry, but it shows only zeros when I try to print the supposed reversed stack after the recursion takes place. Here is my code:
//Class to reverse a stack using recursion
class ReverseStack
{
//Global Variables
static int[] stack = new int[5];
static int[] tempStack = new int[5];
private static int size;
//Constructor
public ReverseStack()
{
}
//Functions to for the stack
public static boolean isEmpty()
{
return size == 0;
}
//Function to determine if stack is full
public static boolean isFull()
{
return size == stack.length;
}
//Function to determine size of array
int size()
{
return size;
}
//Function to push entries into stack
public static boolean push(int[] stack, int data)
{
if(isFull())
{
return false;
}
else
{
stack[size] = data;
size++;
return true;
}
}
//Function to remove entries from stack
public static int pop()
{
if(isEmpty())
{
return 0;
}
else
{
size--;
return(stack[size + 1]);
}
}
//Function to print the stack
public static void print(int[] stack)
{
//This prints top to bottom
//Top is the last entry
System.out.println("Top to Bottom");
if(isEmpty())
{
System.out.println("The stack is empty ");
}
else
{
for(int cntr = 0; cntr < size; cntr++)
{
System.out.println(stack[cntr] + " ");
}
}
}
//Function to reverse data recursively
public static void reverseData(int data)
{
//Variables
int tempNum;
int cntr = 4;
int cntr2 = 0;
//Note:
/*
To reverse a stack we need to
1. pass in a number
2. Remove the number
3. Repeat until no numbers are left
4 copy stack
5. print
*/
if(data > stack[cntr - 1])
{
tempStack[cntr2] = data;
cntr--;
cntr2++;
data = stack[cntr - 1];
reverseData(data);
}
}
}
I call this reverseStack function in my program's menu system:
//Function to create a menu system
public static void menu()
{
//Variables
int response;
//Message user
System.out.println("Would you like to: "
+ "\n(1) Reverse a stack using recursion "
+ "\n(2) Draw the Sierpinski Triangle "
+ "\n(3) Draw the Dragon Curve "
+ "\n(4) Recurse through a file/directory system"
+ "\n(5) Recurse through my own recursive function"
+ "\n(6) Quit the program ");
//Save user's response
response = Integer.parseInt(myScanner.nextLine());
//Switch statement for menu options
switch (response)
{
case 1:
{
//Create a new instance of ReverseStack class
ReverseStack rs = new ReverseStack();
//Add data into stack before reversing the stack
rs.push(stack, 10);
rs.push(stack, 20);
rs.push(stack, 30);
rs.push(stack, 40);
rs.push(stack, 50);
//Print stack
rs.print(stack);
//Call function to reverse data set
rs.reverseData(stack[4]);
//Print data set
rs.print(rs.tempStack);
//Return to menu
menu();
break;
}
}
}
Do you know what I may be doing wrong?
Size seems to be always 1 above the index of the last element in the stack, so your pop method should probably be
size--;
return stack[size]; // not stack[size+1]
Also your reverseData function is not working because you are resetting cntr and cntr2 each time the function is called. Those must be global variables.
Maybe try something like
int counter = 0;
public void reverseData (int index) {
if (index > counter) {
int temp = data[index];
data[index] = data[counter];
data[counter] = temp;
counter++;
reverseData(--index);
}
You need to know the next index of your tempStack. Right now it is always 0. So you are only updating the first value and rest are 0s
Change your method
//Function to reverse data recursively
public static void reverseData(int data)
{
//Variables
int tempNum;
int cntr = 4;
int cntr2 = 0;
//Note:
/*
To reverse a stack we need to
1. pass in a number
2. Remove the number
3. Repeat until no numbers are left
4 copy stack
5. print
*/
if(data > stack[cntr - 1])
{
tempStack[cntr2] = data;
cntr--;
cntr2++;
data = stack[cntr - 1];
reverseData(data);
}
}
with this
//Function to reverse data recursively
public static void reverseData(int data, int cntr2)
{
//Variables
int tempNum;
int cntr = 4;
//Note:
/*
To reverse a stack we need to
1. pass in a number
2. Remove the number
3. Repeat until no numbers are left
4 copy stack
5. print
*/
if(data > stack[cntr - 1])
{
tempStack[cntr2] = data;
cntr--;
cntr2++;
data = stack[cntr - 1];
reverseData(data, cntr);
}
}
In your main method, call reverseData(stack[4], 0)
Or create cntr2 as class level variable
If it is a temp stack please not define it as static variable. It is not safe and not good coding behavior.
You used two pointers. The cntr points to the last variable, and the cntr2 points to the first variable. Why not compare them?
For example, keep recursing until the cntr2 less than cntr.

Problem in implementing the methods according to test file

I was able to make the Constructor and capacity methods to works but don;t know why size(),isFull() and isEmpty() fails.I believe its pretty simple but i am just unable to see a minor error and fix it.Hope someone can clarify what i am doing wrong with thorough explaination.Also,my constructor works with the test file and it passes,but just want to know Is my constructor correct as specified by question?
import java.util.Arrays;
import java.util.Iterator;
public class SortedArray<T extends Comparable> implements
java.lang.Iterable<T> {
public SortedArray(int capacity) {
this.array = (T[]) new Comparable[0];
this.capacity = capacity;
this.size = 0;
}
public SortedArray(int capacity, T[] data) {
if(capacity > data.length)
{
this.capacity = capacity;
}
else {
this.capacity = data.length;
}
this.size = data.length;
this.array = (T[]) new Comparable[0];
}
final public int size() {
return this.size
}
final public int capacity() {
return this.capacity;
}
final boolean isEmpty() {
return size == 0;
}
final boolean isFull(){
return size == capacity;
}
#Override
final public Iterator<T> iterator() {
// Do not modify this method.
return Arrays.stream(array).iterator();
}
// Do not modify these data members.
final private T[] array; // Storage for the array's element
private int size; // Current size of the array
final private int capacity; // Maximum size of the array
}
//// Test File:
#Test
public void testConstructor() {
System.out.println("Constructors");
SortedArray array = new SortedArray(20);
assertEquals(array.size(), 0);
assertEquals(array.capacity(), 20);
Integer[] data = {1, 2, 3, 4};
array = new SortedArray(20, data);
assertEquals(array.size(), 4);
assertEquals(array.capacity(), 20);
array = new SortedArray(2, data);
assertEquals(array.size(), 4);
assertEquals(array.capacity(), 4);
}
#Test
public void testSize() {
System.out.println("size");
SortedArray arr = new SortedArray(10);
// Array is initially empty
assertEquals(arr.size(), 0);
// Inserting elements increases size
arr.add(12);
arr.add(13);
arr.add(14);
assertEquals(arr.size(), 3);
// Inserting duplicates increases size
arr.add(12);
arr.add(13);
assertEquals(arr.size(),5);
// Fill up the array
for(int i = 0; i < 5; ++i)
arr.add(i);
assertEquals(arr.size(), 10);
// Size does not change when array is full
arr.add(10);
arr.add(11);
assertEquals(arr.size(), 10);
// Removing elements decreases size
arr.remove(0);
arr.remove(1);
arr.remove(2);
assertEquals(arr.size(), 7);
// but removing elements that don't exist doesn't change anything
arr.remove(100);
assertEquals(arr.size(), 7);
// Removing from the empty array doesn't change size.
SortedArray empty = new SortedArray(10);
empty.remove(10);
assertEquals(empty.size(), 0);
}
#Test
public void testCapacity() {
System.out.println("capacity");
SortedArray array = new SortedArray(20);
assertEquals(array.capacity(), 20);
array = new SortedArray(100);
assertEquals(array.capacity(), 100);
Integer[] data = {1,2,3,4,5,6,7,8,9,0};
array = new SortedArray(20, data);
assertEquals(array.capacity(), 20);
array= new SortedArray(5, data);
assertEquals(array.capacity(), 10);
}
#Test
public void testIsEmpty() {
System.out.println("isEmpty");
SortedArray array = new SortedArray(10);
assertTrue(array.isEmpty());
array.add(10);
assertFalse(array.isEmpty());
array.remove(10);
assertTrue(array.isEmpty());
}
#Test
public void testIsFull() {
System.out.println("isFull");
SortedArray array = new SortedArray(5);
assertFalse(array.isFull());
array.add(10);
array.add(11);
array.add(12);
array.add(13);
array.add(14);
assertTrue(array.isFull());
array.remove(10);
assertFalse(array.isFull());
}
#Test
public void testIterator() {
}
testSize Failed : Expected <0> but was <3>
testCapacity Failed : Expected <5> but was <10>
testConstructor Failed : Expected <0> but was <4>
testisFull Failed : jUnit.framework.AssertionFailedError
testisEmpty Failed : jUnit.framework.AssertionFailedError
You forgot to include your "add(T toAdd)" and "remove(T toRemove)" methods, which when I was going through to make the tests pass, was the source of a vast majority of the fails. (Note: a trace of the fails would help, since your adds and removes need to be pretty complicated to fit the design it seems you intend)
Anyways, on to fixing what I can see.
In your second constructor, you never actually assign the data you take in. You call this.array = (T[]) new Comparable[0]; which creates an empty array of type Comparable. In reality, you need to call this.array = data in order to keep what's been given to you.
Another thing, in your size() method you forgot to place a semicolon after this.size. That tends to prevent things from passing.
Finally, final private T[] array can't have final, or you'll never be able to add or remove elements.
As a bonus, here are the add() and remove() methods I used to fit the requirements and make the tests pass (with comments!!!!):
public void add(T t) {
if (!(size >= capacity)) { //If there's room...
if (size == 0) //If the array is empty...
array[0] = t; //Add to first index
else
array[size] = t; //Add to next available index
size++;
}
}
public void remove(T element) {
if (size <= 0) //If the array is empty...
return; //Stop here
else {
for (int i = 0; i <= this.size(); i++) { //Linear search front-to-back
if (array[i].equals(element)) { //Find first match
array[i] = null; //Delete it
size--;
if (i != size) { //If the match was not at the end of the array...
for (int j = i; j <= (this.size() - 1); j++)
array[j] = array[j + 1]; //Move everything after the match to the left
}
return; //Stop here
}
}
}
}
On a side note, your calls to create SortedArray objects should really be parameterized (Using the <> such as SortedArray<Integer> arr = new SortedArray<Integer>(5, data);).

Why am I getting wrong 0 index of value?

I am trying to learn how to add dynamically data into a list but I am facing a problem.
Why am I getting wrong value index of 0. when ever I trying to add a value position of index.
import java.util.*;
public class MyList{
String[] mList = null;
int pointer;
public MyList(){
mList = new String[pointer];
}
public void add(String aStringValue){
System.out.println("add: "+pointer+ " " +aStringValue+ " "+mList.length);
if (pointer < mList.length-1) {
System.out.println(pointer+ " " +aStringValue);
mList[pointer] = aStringValue;
pointer++;
}else{
System.out.println("New List:");
String[] lStringList = new String[mList.length + 20];
System.arraycopy(mList, 0, lStringList, 0, mList.length);
mList = lStringList;
System.out.println("New List: "+mList.length);
}
}
public int size(){
int size = 0;
for (int i = 0;i<mList.length;i++) {
if (mList[i] == null) {
return size;
}else{
size++;
}
}
return size;
}
public String get(int index){
return mList[index];
}
}
public class ListSize{
public static void main(String[] args){
MyList lList = new MyList();
lList.add("Amit");
lList.add("Deepak");
lList.add("Vishal");
lList.add("hello");
lList.add("abc");
lList.add("rahul");
lList.add("ajit");
lList.add("durgesh");
lList.add("a");
lList.add("b");
lList.add("c");
lList.add("d");
lList.add("e");
System.out.println("MyList is: "+lList.size());
for (int i = 0; i<lList.size(); i++) {
System.out.println(lList.get(i));
}
}
}
I expect the Output of Amit, Deepak but the Actual output is Deepak, vishal
When you create a new array, you don't add anything to it. I suggest you always check the size is ok, and afterwards, always add the element. If you want to see this clearly, I suggest stepping through the code in your debugger.
public void add(String aStringValue) {
// ensure capacity.
if (pointer == mList.length)
mList = Arrays.copyOf(mList, mList.length + 20);
mList[pointer++] = aStringValue;
}
In your add method, if the array hasn’t got room for the string you want to add, you are creating a new and bigger array, but not adding the string to the new array.
I believe that the code in the if part of your if statement should go after the if statement instead.

Getting a weird NoSuchElementException

We are trying to compile our program, but we keep getting a NoSuchElementException. Anyone that has a clue on why this keeps occurring? Thanks in advance. In the following I will attach both the code where we implement the exception and also the main method.
EDIT - whole code in the following:
import java.util.Iterator;
import edu.princeton.cs.algs4.*;
public class RandomQueue<Item> implements Iterable<Item> {
private Item[] queue;
private int N;
private int size;
// Your code goes here.
public RandomQueue() { // create an empty random queue
N = 0;
size = 2;
queue = (Item[]) new Object[size];
}
public boolean isEmpty() {// is it empty?
if(N == 0) {
return true;
} else {
return false;
}
}
public int size() {// return the number of elements
return size;
}
public void resizeArray() {
if(3/4*size < N) {
size = size*2;
Item[] queueUpdated = (Item[]) new Object[size];
for(int i = 0; i < queue.length; ++i) {
queueUpdated[i] = queue[i];
}
queue = queueUpdated;
} else if (N < 1/4*size) {
size = size/2;
Item[] queueUpdated = (Item[]) new Object[size];
for(int i = 0; i < size-1; ++i) {
queueUpdated[i] = queue[i];
}
queue = queueUpdated;
}
}
public void enqueue(Item item) {// add an item
if(N < queue.length) {
queue[N++] = item;
resizeArray();
}
}
public Item sample(){ // return (but do not remove) a random item
if(isEmpty()) {
throw new RuntimeException("No such elements");
} else {
return queue[StdRandom.uniform(N)];
}
}
public Item dequeue(){ // remove and return a random item
if(isEmpty()) {
throw new RuntimeException("Queue is empty");
} else {
System.out.println(N);
int indexFraArray = StdRandom.uniform(N);
Item i = queue[indexFraArray];
queue[N] = null;
queue[indexFraArray] = queue[N--];
resizeArray();
return i;
}
}
private class RandomQueueIterator<E> implements Iterator<E> {
int i = 0;
public boolean hasNext() {
return i < N;
}
public E next() {
if (!hasNext()) {
throw new java.util.NoSuchElementException(); // line 88
}
i++;
return (E) dequeue();
}
public void remove() {
throw new java.lang.UnsupportedOperationException();
}
}
public Iterator<Item> iterator() { // return an iterator over the items in
random order
return new RandomQueueIterator();
}
// The main method below tests your implementation. Do not change it.
public static void main(String args[]) {
// Build a queue containing the Integers 1,2,...,6:
RandomQueue<Integer> Q = new RandomQueue<Integer>();
for (int i = 1; i < 7; ++i) Q.enqueue(i); // autoboxing! cool!
// Print 30 die rolls to standard output
StdOut.print("Some die rolls: ");
for (int i = 1; i < 30; ++i) StdOut.print(Q.sample() +" ");
StdOut.println();
// Let's be more serious: do they really behave like die rolls?
int[] rolls= new int [10000];
for (int i = 0; i < 10000; ++i)
rolls[i] = Q.sample(); // autounboxing! Also cool!
StdOut.printf("Mean (should be around 3.5): %5.4f\n", StdStats.mean(rolls));
StdOut.printf("Standard deviation (should be around 1.7): %5.4f\n",
StdStats.stddev(rolls));
// Now remove 3 random values
StdOut.printf("Removing %d %d %d\n", Q.dequeue(), Q.dequeue(), Q.dequeue());
// Add 7,8,9
for (int i = 7; i < 10; ++i) Q.enqueue(i);
// Empty the queue in random order
while (!Q.isEmpty()) StdOut.print(Q.dequeue() +" ");
StdOut.println();
// Let's look at the iterator. First, we make a queue of colours:
RandomQueue<String> C= new RandomQueue<String>();
C.enqueue("red"); C.enqueue("blue"); C.enqueue("green");
C.enqueue("yellow");
Iterator<String> I = C.iterator();
Iterator<String> J = C.iterator();
StdOut.print("Two colours from first shuffle: "+I.next()+" "+I.next()+" ");
StdOut.print("\nEntire second shuffle: ");
while (J.hasNext()) StdOut.print(J.next()+" ");
StdOut.println("\nRemaining two colours from first shuffle: "+I.next()+" "+I.next()); // line 142
}
}
I compile in cmd and this is the error I get
the error happens here:
enter image description here
and here:
enter image description here
Your iterator is modifying your collection. This is non-standard at least and seems to confuse yourself.
You are creating two iterators over your queue C, which has 4 elements in it at this time:
Iterator<String> I = C.iterator();
Iterator<String> J = C.iterator();
You ask the former iterator for two elements:
StdOut.print("Two colours from first shuffle: "+I.next()+" "+I.next()+" ");
This removes (dequeues) those two elements through this line:
return (E) dequeue();
Now your queue has 2 elements in it. N is 2.
Your try to remove the remaining 2 elements here:
StdOut.print("\nEntire second shuffle: ");
while (J.hasNext()) StdOut.print(J.next()+" ");
However, after one element has been removed, J.i is 1 and N is 1, so the iterator J considers the queue exhausted and only gives you this one element. There’s one left. N is 1. Yet you try to remove another two elements:
StdOut.println("\nRemaining two colours from first shuffle: "+I.next()+" "+I.next()); // line 142
This is bound to fail. Fortunately it does. next calls hasNext, which in turn compares:
return i < N;
I.i is 2 (since we had previously taken 2 elements from I) and N is 1, so hasNext returns false, which causes next to throw the exception.
The solution is simple and maybe not so simple: Your iterator should not remove any elements from your queue, only return the elements in order.
And the real answer: You should learn to use a debugger. It will be a good investment for you.

Sorting a integer list without a sort command

So I have this code:
public class SortedIntList extends IntList
{
private int[] newlist;
public SortedIntList(int size)
{
super(size);
newlist = new int[size];
}
public void add(int value)
{
for(int i = 0; i < list.length; i++)
{
int count = 0,
current = list[i];
if(current < value)
{
newlist[count] = current;
count++;
}
else
{
newlist[count] = value;
count++;
}
}
}
}
Yet, when I run the test, nothing prints out. I have the system.out.print in another class in the same source.
Where am I going wrong?
EDIT: Print code from comment:
public class ListTest
{
public static void main(String[] args)
{
SortedIntList myList = new SortedIntList(10);
myList.add(100);
myList.add(50);
myList.add(200);
myList.add(25);
System.out.println(myList);
}
}
EDIT2: Superclass from comment below
public class IntList
{
protected int[] list;
protected int numElements = 0;
public IntList(int size)
{
list = new int[size];
}
public void add(int value)
{
if (numElements == list.length)
System.out.println("Can't add, list is full");
else {
list[numElements] = value; numElements++;
}
}
public String toString()
{
String returnString = "";
for (int i=0; i<numElements; i++)
returnString += i + ": " + list[i] + "\n";
return returnString;
}
}
Let's walk through the logic of how you want it to work here:
first you make a new sorted list passing 10 to the constructor, which make an integer array of size 10.
now you call your add method passing 100 into it. the method sets position 0 to 100
now you add 50, the method sets 50 in position 0 and 100 in position 1
now you add 200, which gets placed at position 2
and you add 25. which gets set to position 0, and everything else gets shuffled on down
then your method will print out everything in this list.
So here are your problems:
For the first add, you compare current, which is initialized at 0, to 50. 0 will always be less than 50, so 50 never gets set into the array. This is true for all elements.
EDIT: Seeing the super class this is how you should look to fix your code:
public class SortedIntList extends IntList
{
private int[] newlist;
private int listSize;
public SortedIntList(int size)
{
super(size);
// I removed the newList bit becuase the superclass has a list we are using
listSize = 0; // this keeps track of the number of elements in the list
}
public void add(int value)
{
int placeholder;
if (listSize == 0)
{
list[0] = value; // sets first element eqal to the value
listSize++; // incriments the size, since we added a value
return; // breaks out of the method
}
for(int i = 0; i < listSize; i++)
{
if (list[i] > value) // checks if the current place is greater than value
{
placeholder = list[i]; // these three lines swap the value with the value in the array, and then sets up a comparison to continue
list[i] = value;
value = placeholder;
}
}
list[i] = value; // we are done checking the existing array, so the remaining value gets added to the end
listSize++; // we added an element so this needs to increase;
}
public String toString()
{
String returnString = "";
for (int i=0; i<listSize; i++)
returnString += i + ": " + list[i] + "\n";
return returnString;
}
}
Now that I see the superclass, the reason why it never prints anything is clear. numElements is always zero. You never increment it because you never call the superclass version of the add method.
This means that the loop in the toString method is not iterated at all, and toString always just returns empty string.
Note
This is superseded by my later answer. I have left it here, rather than deleting it, in case the information in it is useful to you.
Two problems.
(1) You define list in the superclass, and presumably that's what you print out; but you add elements to newList, which is a different field.
(2) You only add as many elements to your new list as there are in your old list. So you'll always have one element too few. In particular, when you first try to add an element, your list has zero elements both before and after the add.
You should probably have just a single list, not two of them. Also, you should break that for loop into two separate loops - one loop to add the elements before the value that you're inserting, and a second loop to add the elements after it.

Categories

Resources