JAVA Queue Implementation using Arrays - java

I'm trying to implement Queues in JAVA. I'm a beginner. I dont understand why this isn't working. Push() works fine but pop() isn't working. Can someone please point out where im going wrong?
pop():
public void pop()
{
for(int i=0;i<length;i++)
{
while(i<(length-1))
{
arr[i]=arr[i+1];
}
}
}
push():
public void push(int x)
{
push:for(int i=0;i<length;i++)
{
if(arr[i]==null)
{
arr[i]=x;
break push;
}
}
}
show():
public void show()
{
int c=0;
for(int i=0;i<length;i++)
//if(arr[i]!=null)
{
System.out.println(arr[i]);
c++;
}
System.out.println("Current Capacity "+c+"/"+length);
}
main()
public static void main(String...i)
{
System.out.println("Stack Implementation");
Queue stack = new Queue();
System.out.println("Push");
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.push(5);
stack.show();
System.out.println("Pop");
stack.pop();
stack.show();
}
The output doesn't show any data after pop() is run.

You don't increment i in pop() so the while loop will run endlessly.
In push you are using a for loop which increments i: :for(int i=0;i<length;i++ /*here*/)
You also don't initialize i in pop() so it will probably have the value of the last increment in push(). That value will be the index of the next empty element (if there's one left) and thus that's wrong anyways. However, you want to pop from the front, so you'd need to start at i = 0 - in that case another for loop would work as well, i.e. you just copy the value of element at i+1 to the index i and set the last element to null (for more efficiency you could stop once i+1 has a null element).
Edit: now that you've posted more code for pop() the situation is a little different. You are already using a for loop in pop() but another loop inside that. I assume you want to do if(i<(length-1)) instead of while(i<(length-1)) - but in that case you'd still have to handle the last element, i.e. once the queue was full you'd need to set the last element to null when you pop one and move the rest.

When you pushed the element you need to return from the method:
public void push(int x) {
for (int i = 0; i < length; i++) {
if (arr[i] == null) {
arr[i] = x;
return; // Exit from push when you added the element in the right position
}
}
}
Note that this code is not optimized. Push an element requires O(n), so can waste a lot of time for big queues, but this is the closest solution to your code. Anyway a simple optimization can be done introducing a variable holding the last used index. So you can use that variable to push and pop an element in O(1).

Related

Use arraydeque to implement MonitonicQueue

I'm using the Deque to implement a monotonic queue. I know that Deque can be created by both ArrayDeque and LinkedList. Here is the Monotonic class I constructed:
public static class MonotonicQueue {
Deque<Integer> monotonicQueue;
public MonotonicQueue() {
monotonicQueue = new ArrayDeque<>();
}
void push(int n) {
while (!monotonicQueue.isEmpty() && monotonicQueue.getLast() < n) {
monotonicQueue.removeLast();
}
monotonicQueue.addLast(n);
}
int max() {
return monotonicQueue.getFirst();
}
void pop(int n) {
if (!monotonicQueue.isEmpty() && n == monotonicQueue.getFirst()) {
monotonicQueue.removeFirst();
}
monotonicQueue.addLast(n);
}
}
However, the issue appears in the void push(int n) method, which means delete all elements which are < n, and then add n into the queue of the tail. I initialized a variable window in a method and then tried to push an element to update this monotonic queue.
MonotonicQueue window = new MonotonicQueue();
window.push(3);
But it even fails to insert the first element. The weird thing is when I use the second way in the constructor, say LinkedList<> instead of ArrayDeque, it works very well, i.e. 3 can be inserted successfully.
public MonotonicQueue() {
monotonicQueue = new LinkedList<>();
}
I am wondering why one way works but the other can't. What happened here? Thank you!

Is this the right way to use method "add"?

So my friend created a queue class which has an instance variable size = 0; and for the add method he uses.
But what will happen to index 0 in this case?
It will not have an elements declared to it since add starts from size++. Which is 1 starting position.
public void add(T data) {
if(size > elements.length) {
throw new QueueException("Queue is full");
}
elements[size++] = data;
}
size++ returns the size value before it gets incremented in the background. Because of that the elements[0] will be assigned. See Oracle Tutorial on incrementing.
The problem is with the last element. The code will attempt to assign elements[elements.length] which is above the array capacity. The guard should be:
if (size >= elements.length) {
throw new QueueException("Queue is full");
}

Iterator stack hasNext() not returning true

I'm trying to iterate over an Object array. Using the next() method works so I'm guessing that my iterator class and constructors are working.
For some reason i'm not getting any output while the hasNext() method is running.
Iterator it = hej.iterator();
Object j = it.next();
System.out.println(j);
while(it.hasNext()){
Object i = it.next();
System.out.println(i + " ");
}
With "hej" being my Object array.
My code for the next(); and hasNext() methods are as follows:
public class StackIterator implements Iterator<Object>{
// fields
private int element = 0;
private final Object[] elements;
private final int max;
// constructor
public StackIterator(Object[] values, int maxIndex) {
elements = values;
max = maxIndex;
}
// methods
public boolean hasNext() {
return element < max;
}
public Object next() {
return elements[element++];
}
}
The file that constructs the Object Array and the Object Array depends on an interface:
public interface Stack {
int size();
boolean isEmpty();
void push(Object element);
Object pop();
Object peek();
Iterator<Object> iterator();
}
The methods are then explained in another file:
public class StackExample implements Stack {
// fields
int length = 0;
Object[] arr;
// constructor
public StackExample() {arr = new Object[length];}
// method returns size of object array
public int size() {
return arr.length;
}
// method checks if object is empty
public boolean isEmpty() {
boolean result = false;
if (arr.length == 0){
result = true;
}
return result;
}
// method for push
public void push(Object element) {
newBiggerObj();
arr[0] = element;
}
// returns the first object of the stack
public Object pop() {
Object[] temp = new Object[arr.length-1];
Object first = arr[0];
for (int i = 0; i<arr.length-1; i++){
temp[i] = arr[i+1];
}arr = temp;
return first;
}
// returns the object on top of stack
public Object peek() {
if (isEmpty()){
try{
throw new Exception("Stack empty, can't peek!");
}
catch(Exception e){
return e.getMessage();
}
}
else {
Object first = arr[0];
return first;
}
}
// method for push method
private void newBiggerObj(){
Object[] temp = new Object[arr.length+1];
for (int i = 0; i<arr.length; i++){
temp[i+1] = arr[i];
}
arr = temp;
}
public String toString(){
String str = "";
for (int i = 0; i < arr.length; i++){
str = str + arr[i] + " , ";
}return str;
}
public Iterator<Object> iterator() {
return new StackIterator(arr, length);
}
}
What bothers me is that the method Iterator is within itself returning an instance of the class Stack Iterator. Which i posted above. So my real problem seems to be that my fields are not being given any value, since I am not myself giving the any values within the constructor.
My main method in which I'm testing all of this is as follows:
public class Teststack {
public static void main(String[] args){
// new instane of class StackExample
StackExample hej = new StackExample();
// test for the different methods
System.out.println(hej.isEmpty());
System.out.println(hej.size());
hej.push(4);
hej.push("hej");
hej.push(6);
hej.push(5);
System.out.println(hej.size());
System.out.println(hej.peek());
System.out.println(hej.pop());
System.out.println(hej.toString());
System.out.println(hej.isEmpty());
System.out.println("Testing Iterator: ");
// test for iterator
Iterator it = hej.iterator();
Object j = it.next();
System.out.println(j);
while(it.hasNext()){
Object i = it.next();
System.out.println(i + " ");
}
}
}
In your StackExample class, I don't see the length variable being updated when elements are pushed or popped. Due to this, length will always be 0 and calls to it.hasNext() will always return false.
You don't need to pass the length as a separate argument. You can find the array's length in the StackIterator constructor and use it.
Also note that since you're creating a new array on every push and pop, the iterator returned by StackExample#iterator() will become stale after every push/pop since it will work on an old copy/state of the stack.
The problem is here:
public Iterator<Object> iterator() {
return new StackIterator(arr, length);
}
length field is never changed, so its value is always 0. You can change the code to this:
public Iterator<Object> iterator() {
return new StackIterator(arr, arr.length);
}
Also, before retrieving elements from the iterator, you should always call it.hasNext. The fact you did this:
Iterator it = hej.iterator();
Object j = it.next();
And worked was just pure luck.
Apart of this, I can sense you have a bad design on your stack implementation. Here are some hints to improve your code:
The inner array should be initialized with a default size different than 0. E.g. 10 (as done in java.util.ArrayList implementation).
You should avoid creating a new array when adding (push) or removing (pop) an element from your stack. Instead of this, you should use the length field to control how many elements are in your stack.
The value of the new size should be based on another formula rather than array.length + 1. For example, try using something like int newSize = array.length / 2 * 3;.
Resize the inner array only when necessary. When calling push, do it only if you precisely need to increase the size of the array. When calling pop, do it if the current length of the array (this is, array.length) is far greater than the value of length field of your class.
Never forget to update the value of length on push and pop methods.
Couple of issues:
You are calling Object j = it.next(); after creating iterator and then check for hasNext. You are incrementing the element index. Hence if you just have one element, you wont enter the while loop. In addition, if your custom datastructure is empty i.e. array has no elements then you are prone to ArrayIndexOutOfBoundException.
You will always iterate and print n-1 elements instead to n elements.
Once you iterated, then your pointer will always point to last element and never get resetted. So very next time you wont be able to iterate over your elements. Its a one time iterator.
Try not to call
Object j = it.next() statement, but just while cycle. Seems you have an array of just 1 element.
There are a number of problems with this code:
In the StackIterator constructor there is no bounds checking on maxIndex. Callers can pass in a number greater than values.length, less that 0, etc.
In the next method, there is no check of the end condition, either directly or by calling hasNext(). Callers can keep calling next() and see elements beyond max or even get an ArrayIndexOutOfBoundsException, when they should be getting a NoSuchElementException.
The Stack class never increments or decrements its length field when elements are pushed or popped.
The Stack class tracks the length separately from the array, even though it always resizes the array on every push or pop, but Java arrays already know their size. (But see the next item.)
The Stack class resizes the array on every push or pop, which is very inefficient. Typically classes like this only resize the array when necessary, allowing 'slack' space, to give amortized constant time performance (see ArrayList). If you do this, however, it is necessary to null out popped items to avoid unintentional object retention.
The Stack adds and removes elements at the beginning of the array. This is incredibly inefficient since it means a O(n) reshuffling must be done on every push or pop.
The peek() method takes into account the possibility that the Stack may be empty, but the pop() method does not. A pop() on an empty Stack will throw an ArrayIndexOutOfBoundsException.
Stack is not a generic class. It holds Object. Users of the Stack will have to cast the return values from peek() or pop(), and it isn't type safe. In your example, you show a stack that is a heterogeneous mixture of String and Integer. This is a very Java 1.2 way of doing things, and while it isn't necessarily wrong, you should consider parameterizing Stack.

Loop through Circular list Java

I want to create a method that loops though a circular linked list, Essentially mimicking a token ring network. I create a random number of either 0 or 1, if it is 0, it deletes the first item in the list. If it is one it just says they are still logged on.
So i should have something like this..
User A Logged on
User B logged off
User A logged off
When list is clear it terminates
The problem is it seems to always leave one particular user....How can I make this work?
public void log(){
if(start==null)
System.out.println("List is empty..");
else{
Node temp=start;
System.out.print("->");
//get rid of each user with a similar method but with a random user removed....
while(temp.next!=null && count>0)
{
int r = rand.nextInt(2);
if(r==0)
{
deleteAt(0);
System.out.println(" OFF"+temp.data);
}
else if(r==1)
{
System.out.println(" ON "+temp.data);
}
temp=temp.next;
}
//System.out.println(counter);
}
}
public void deleteFirst() {
Node temp=start;
while(temp.next!=start){
temp=temp.next;
}
temp.next=start.next;
start=start.next;
count--;
}
public void deleteAt(int position){
Node current=start;
Node previous=start;
for(int i=0;i<position;i++){
if(current.next==start)
break;
previous=current;
current=current.next;
}
if(position==0)
deleteFirst();
else
previous.next=current.next;
count--;
}
Deleting the last element from a circular linked list is a special case, because you need to set start to null. So you need to cater for that in your delete routines: test whether start->next == start.
Besides that, looping through the list while deleting elements requires special care: temp in the outer loop in log() can point to the removed element, rather than an element in the list. Taking temp=temp->next then may not be valid.
Also, count is decremented twice in deleteAt(0).

java stack reading from an array throws ArrayIndexOutOfBoundsException

I need to fill a stack from an array, then print out the elements in order and then again reversing the order. What I'm having problems with is I'm getting an ArrayIndexOutOfBoundsException and cant figure out where it is coming from. I have tried running through the debug and it appears as I'm popping off elements it never reaches the last element. Below is my code:
public class arrayStack {
private int top;
private String[] storage;
public arrayStack(int capacity)
{
storage = new String[capacity];
top = -1;
}
public boolean isEmpty() {
return (top == 0);
}
String peek() {
return storage[top];
}
String pop() {
top--;
return storage[top];
}
public void push(String str) {
top++;
storage[top] = str;
}
}
StackMain.java:
public class StackMain {
public static void main(String[] args) {
//int j = 5;
String[] list = new String[5];
list[0] = "Beware";
list[1] = "The";
list[2] = "Ides";
list[3] = "Of";
list[4] = "March";
arrayStack stack = new arrayStack(5);
for(int i = 0; i < list.length; i++)
{
stack.push(list[i]);
}
for(int j = 0; j < list.length; j++)
System.out.println(stack.pop());
}
}
In pop(), you need to return the item that was popped, which is the item at the index of the old value of top. Cleanest way is to change the function to
String pop() {
return storage[top--];
}
Edit
You also need to change isEmpty() to return (top == -1). You could also change the implementation to use size (the number of elements) instead of top (the index of the highest element) like others mentioned.
In your constructor for arrayStack, you should set top to 0, rather than to -1. In your isEmpty method, you even check that top == 0, so clearly top == 0 means empty, rather than top == -1. This is why you always miss the last element when popping off values from the stack; putting the first element increments top to 0.
Oh, and I missed what tom said, below: decrementing top before you find the value at the top will return the wrong element. His code below is preferable, but this might be more easy to understand for a beginner:
public String pop() {
String topValue = storage[top];
top--;
return topValue;
}
If you push(String) just one element, with top initialized to -1, what will the value of top be after the push?
Now look at your pop() function, it decrements top before trying to get the element requested, so what array index is it going to try to access if you've pushed just one element?
Since you start top at -1, once you have added your 5 elements from the String array top will be 4, which is incorrect since you have 5 elements.
Then when you try to pop the stack 5 times, top goes back to -1 and storage[-1] doesn't exist so you get an ArrayIndexOutOfBoundsException
Start top at 0.
Alternatively if you decrement top after you retrieve the element from you stack, you won't get an error; but it would be better to start top at 0 because top is really representing the number of elements in your stack.
Please tag the question as homework. And coming to the problem, the problem is in the pop() function. You are decrementing the value of top first and then returning the element. But when you check the push() function, you are incrementing first and then adding the element. So, if you move the top-- to after getting the element from the stack your problem will be solved.
Your pop method is incorrect. In your code here, top starts at negative 1.
When you push an element, top becomes 0.
When you pop an element, the top becomes -1 before you access the element.
Also, your empty method is incorrect. In the initial state of the stack, top = -1, and isEmpty checks if it returns 0. Initially the stack should be empty.
your pop() function must be changed. You must store storage[pop] in a temporary variable and then reduce top by 1 and then return the temporary variable
It would be great if you can include java 1.5 generics facility to implement stack.Then your stack will be more flexible.It can hold any type of objects(in you case only Strings)
And one more advice is in the pop method you should tell garbage collector to discard to poped object as follows. (In the case if you are using generics) Following is a more flexible stack implementation which mentioned in effective java edition 2.
// Initial attempt to generify Stack = won’t compile!
public class Stack<E> {
private E[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = (E[])new E[DEFAULT_INITIAL_CAPACITY];
}
public void push(E e) {
ensureCapacity();
elements[size++] = e;
}
public E pop() {
if (size==0)
throw new EmptyStackException();
E result = elements[--size];
elements[size] = null; // Eliminate obsolete reference
return result;
}

Categories