forked from Hithomelabs/Princeton1
105 lines
2.6 KiB
Java
105 lines
2.6 KiB
Java
package com.hithomelabs.princeton1.module4;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import javax.annotation.Nonnull;
|
|
|
|
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;
|
|
}
|
|
};
|
|
}
|
|
}
|