Checking in Queue implementation of Array

This commit is contained in:
hitanshu310 2025-01-27 00:05:30 +05:30
parent a1c1b2a0f4
commit 09ec2b8bb0
5 changed files with 160 additions and 17 deletions

6
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@ -0,0 +1,22 @@
package com.hithomelabs.clients;
import com.hithomelabs.princeton1.module4.ArrayQueue;
import com.hithomelabs.princeton1.module4.ArrayStack;
import com.hithomelabs.princeton1.module4.Queue;
import com.hithomelabs.princeton1.module4.Stack;
public class ArrayQueueClient {
public static void main(String[] args) {
Queue<Integer> queue = new ArrayQueue<Integer>();
for(int i = 0; i < 21; i++){
queue.enqueue(i);
}
for(int i = 0; i < 13; i++){
System.out.println(queue.dequeue());
}
// Using object s, as stack is generic but every java Object has implementation of toString()
for (Object s : queue)
System.out.println(s);
}
}

View File

@ -0,0 +1,103 @@
package com.hithomelabs.princeton1.module4;
import javax.annotation.Nonnull;
import java.util.Iterator;
public class ArrayQueue<E> extends Queue<E>{
// insertion from tail, removal from head
public static final int DEFAULT_CAPACITY = 10;
private int capacity;
private int tail;
private int head;
private int size;
private E[] arr;
public ArrayQueue(){
this(DEFAULT_CAPACITY);
}
public ArrayQueue(int capacity){
this.capacity = capacity;
arr = (E[]) new Object[this.capacity];
size = 0;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public E dequeue() {
if(isEmpty())
return null;
else{
E element = arr[head];
// Garbage collection
arr[head] = null;
head = (head+1)%capacity;
size = size - 1;
if(capacity >= 40 && size < capacity/4){
capacity = capacity/2;
resize(capacity, capacity*2);
}
return element;
}
}
@Override
public void enqueue(E element) {
// We plan capacity expansion if needed
if (size == capacity){
capacity = capacity * 2;
resize(capacity, capacity/2);
}
arr[tail] = element;
tail = (tail + 1) % capacity;
++size;
}
// When resize takes place always the original array is full, so copy the complete array as is
private void resize(int capacity, int oldCapacity) {
E[] resizedArr = (E[]) new Object[capacity];
for(int i = 0; i < size; i++) {
resizedArr[i] = arr[head];
// halving because capacity has now doubled
arr[head] = null;
head = (head + 1) % oldCapacity;
}
arr = resizedArr;
// When resizing takes place, we bring the head to 0 and the tail to size
// tail is where new inserts will be made and head will be where elements will be removed
tail = size;
head = 0;
}
@Override
public int size() {
return size;
}
@Override
@Nonnull
public Iterator<E> iterator() {
return new Iterator<E>() {
int counter = size;
int pointer = head;
@Override
public boolean hasNext() {
return counter != 0;
}
@Override
public E next() {
E element = arr[pointer];
pointer = (pointer + 1)% capacity;
--counter;
return element;
}
};
}
}

View File

@ -1,4 +1,5 @@
package com.hithomelabs.princeton1.module4; package com.hithomelabs.princeton1.module4;
import javax.annotation.Nonnull;
import java.util.Iterator; import java.util.Iterator;
// Concrete implementation of stack using arrays // Concrete implementation of stack using arrays
@ -14,7 +15,7 @@ public class ArrayStack<E> extends Stack<E> {
public ArrayStack(int capacity){ public ArrayStack(int capacity){
this.capacity = capacity; this.capacity = capacity;
this.arr = (E[]) new Object[this.capacity]; arr = (E[]) new Object[this.capacity];
} }
// Constructor chaining, default constructor will call parametrised constructor with default initial capacity 10 // Constructor chaining, default constructor will call parametrised constructor with default initial capacity 10
@ -24,20 +25,20 @@ public class ArrayStack<E> extends Stack<E> {
@Override @Override
public boolean isEmpty() { public boolean isEmpty() {
return this.size == 0; return size == 0;
} }
private void changeCapacity(int newCapacity){ private void changeCapacity(int newCapacity){
E[] resizedArr = (E[]) new Object[newCapacity]; E[] resizedArr = (E[]) new Object[newCapacity];
for (int i = 0; i < this.size; i++) for (int i = 0; i < size; i++)
resizedArr[i] = this.arr[i]; resizedArr[i] = arr[i];
this.arr = resizedArr; arr = resizedArr;
} }
private void incrementSize(){ private void incrementSize(){
if (this.size == this.capacity){ if (size == capacity){
this.capacity = 2 * this.capacity; capacity = 2 * capacity;
changeCapacity(this.capacity); changeCapacity(capacity);
} }
} }
@ -46,8 +47,8 @@ public class ArrayStack<E> extends Stack<E> {
@Override @Override
public void push(E element) { public void push(E element) {
// Lazy approach, we assume size to always be lesser than capacity // Lazy approach, we assume size to always be lesser than capacity
this.incrementSize(); incrementSize();
this.arr[this.size++] = element; arr[size++] = element;
} }
@Override @Override
@ -55,26 +56,27 @@ public class ArrayStack<E> extends Stack<E> {
if (isEmpty()) if (isEmpty())
return null; return null;
else{ else{
E e = this.arr[--this.size]; E e = arr[--size];
this.arr[this.size] = null; arr[size] = null;
this.checkResize(); checkResize();
return e; return e;
} }
} }
private void checkResize() { private void checkResize() {
if (this.size < this.capacity / 4 && this.capacity > 10){ if (size < capacity / 4 && capacity >= 40){
this.capacity = this.capacity / 2; capacity = capacity / 2;
changeCapacity(this.capacity); changeCapacity(capacity);
} }
} }
@Override @Override
public int size() { public int size() {
return this.size; return size;
} }
@Override @Override
@Nonnull
public Iterator<E> iterator() { public Iterator<E> iterator() {
return new Iterator<E>() { return new Iterator<E>() {

View File

@ -0,0 +1,10 @@
package com.hithomelabs.princeton1.module4;
public abstract class Queue<E> implements Iterable<E> {
public abstract boolean isEmpty();
public abstract E dequeue();
public abstract void enqueue(E element);
public abstract int size();
}