forked from Speiger/Primitive-Collections
335 lines
9.2 KiB
Plaintext
335 lines
9.2 KiB
Plaintext
package speiger.src.collections.PACKAGE.queues;
|
|
|
|
import java.util.Arrays;
|
|
import java.util.NoSuchElementException;
|
|
#if TYPE_OBJECT
|
|
import java.util.Comparator;
|
|
import java.util.function.Consumer;
|
|
#endif
|
|
import java.util.Objects;
|
|
|
|
import speiger.src.collections.PACKAGE.collections.COLLECTION;
|
|
import speiger.src.collections.PACKAGE.collections.ITERATOR;
|
|
#if !TYPE_OBJECT
|
|
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
|
|
import speiger.src.collections.PACKAGE.functions.CONSUMER;
|
|
#endif
|
|
import speiger.src.collections.PACKAGE.functions.consumer.BI_OBJECT_CONSUMER;
|
|
import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
|
|
import speiger.src.collections.PACKAGE.utils.ARRAYS;
|
|
|
|
/**
|
|
* A Simple Heap base Priority Queue implementation
|
|
* It is a ArrayBased Alternative to TreeSets that has less object allocations
|
|
* @Type(T)
|
|
*/
|
|
public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE implements PRIORITY_QUEUE KEY_GENERIC_TYPE
|
|
{
|
|
/** The Backing Array */
|
|
protected transient KEY_TYPE[] array = EMPTY_KEY_ARRAY;
|
|
/** The Amount of elements stored within the array */
|
|
protected int size;
|
|
/** The Sorter of the Array */
|
|
protected COMPARATOR KEY_SUPER_GENERIC_TYPE comparator;
|
|
|
|
/**
|
|
* Default Constructor
|
|
*/
|
|
public HEAP_PRIORITY_QUEUE() {
|
|
this(0, null);
|
|
}
|
|
|
|
/**
|
|
* Constructor using custom sorter
|
|
* @param comp Comparator to sort the Array. Can be null
|
|
*/
|
|
public HEAP_PRIORITY_QUEUE(COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
|
|
this(0, comp);
|
|
}
|
|
|
|
/**
|
|
* Constructor with a Min Capacity
|
|
* @param size the initial capacity of the backing array
|
|
* @throws IllegalStateException if the initial size is smaller 0
|
|
*/
|
|
public HEAP_PRIORITY_QUEUE(int size) {
|
|
this(size, null);
|
|
}
|
|
|
|
/**
|
|
* Constructor with a Min Capacity and custom Sorter
|
|
* @param size the initial capacity of the backing array
|
|
* @param comp Comparator to sort the Array. Can be null
|
|
* @throws IllegalStateException if the initial size is smaller 0
|
|
*/
|
|
public HEAP_PRIORITY_QUEUE(int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
|
|
if(size > 0) array = NEW_KEY_ARRAY(size);
|
|
this.size = size;
|
|
comparator = comp;
|
|
}
|
|
|
|
/**
|
|
* Constructor using a initial array
|
|
* @param array the Array that should be used
|
|
*/
|
|
public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array) {
|
|
this(array, array.length);
|
|
}
|
|
|
|
/**
|
|
* Constructor using a initial array
|
|
* @param array the Array that should be used
|
|
* @param size the amount of elements found within the array
|
|
* @throws NegativeArraySizeException if size is smaller then 0
|
|
*/
|
|
public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, int size) {
|
|
this.array = Arrays.copyOf(array, size);
|
|
this.size = size;
|
|
ARRAYS.heapify(array, size, null);
|
|
}
|
|
|
|
/**
|
|
* Constructor using a initial array and a custom sorter
|
|
* @param array the Array that should be used
|
|
* @param comp Comparator to sort the Array. Can be null
|
|
*/
|
|
public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
|
|
this(array, array.length, comp);
|
|
}
|
|
|
|
/**
|
|
* Constructor using a initial array and a custom sorter
|
|
* @param array the Array that should be used
|
|
* @param size the amount of elements found within the array
|
|
* @param comp Comparator to sort the Array. Can be null
|
|
* @throws NegativeArraySizeException if size is smaller then 0
|
|
*/
|
|
public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
|
|
this.array = Arrays.copyOf(array, size);
|
|
this.size = size;
|
|
comparator = comp;
|
|
ARRAYS.heapify(array, size, comp);
|
|
}
|
|
|
|
/**
|
|
* Constructor using a Collection
|
|
* @param c the Collection that should be used
|
|
*/
|
|
public HEAP_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c) {
|
|
array = CAST_KEY_ARRAY c.TO_ARRAY();
|
|
size = c.size();
|
|
ARRAYS.heapify(array, size, null);
|
|
}
|
|
|
|
/**
|
|
* Constructor using a Collection and a custom sorter
|
|
* @param c the Collection that should be used
|
|
* @param comp Comparator to sort the Array. Can be null
|
|
*/
|
|
public HEAP_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
|
|
array = CAST_KEY_ARRAY c.TO_ARRAY();
|
|
size = c.size();
|
|
comparator = comp;
|
|
ARRAYS.heapify(array, size, comp);
|
|
}
|
|
|
|
/**
|
|
* Wrapping method to help serialization
|
|
* @param array the array that should be used
|
|
* @Type(T)
|
|
* @return a HeapPriorityQueue containing the original input array
|
|
*/
|
|
public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array) {
|
|
return wrap(array, array.length);
|
|
}
|
|
|
|
/**
|
|
* Wrapping method to help serialization
|
|
* @param array the array that should be used
|
|
* @param size the amount of elements within the array
|
|
* @Type(T)
|
|
* @return a HeapPriorityQueue containing the original input array
|
|
*/
|
|
public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size) {
|
|
HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new HEAP_PRIORITY_QUEUEBRACES();
|
|
queue.array = array;
|
|
queue.size = size;
|
|
ARRAYS.heapify(array, size, null);
|
|
return queue;
|
|
}
|
|
|
|
/**
|
|
* Wrapping method to help serialization, using a custom sorter
|
|
* @param array the array that should be used
|
|
* @param comp Comparator to sort the Array. Can be null
|
|
* @Type(T)
|
|
* @return a HeapPriorityQueue containing the original input array
|
|
*/
|
|
public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
|
|
return wrap(array, array.length, comp);
|
|
}
|
|
|
|
/**
|
|
* Wrapping method to help serialization, using a custom sorter
|
|
* @param array the array that should be used
|
|
* @param size the amount of elements within the array
|
|
* @param comp Comparator to sort the Array. Can be null
|
|
* @Type(T)
|
|
* @return a HeapPriorityQueue containing the original input array
|
|
*/
|
|
public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
|
|
HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new HEAP_PRIORITY_QUEUEBRACES(comp);
|
|
queue.array = array;
|
|
queue.size = size;
|
|
ARRAYS.heapify(array, size, comp);
|
|
return queue;
|
|
}
|
|
|
|
@Override
|
|
public int size() {
|
|
return size;
|
|
}
|
|
|
|
@Override
|
|
public void clear() {
|
|
#if TYPE_OBJECT
|
|
Arrays.fill(array, null);
|
|
#endif
|
|
size = 0;
|
|
}
|
|
|
|
@Override
|
|
public ITERATOR KEY_GENERIC_TYPE iterator() {
|
|
return new Iter();
|
|
}
|
|
|
|
@Override
|
|
public void enqueue(KEY_TYPE e) {
|
|
if(size == array.length) array = Arrays.copyOf(array, size + 1);
|
|
array[size++] = e;
|
|
ARRAYS.shiftUp(array, size-1, comparator);
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE dequeue() {
|
|
if(size <= 0) throw new NoSuchElementException();
|
|
KEY_TYPE value = array[0];
|
|
array[0] = array[--size];
|
|
#if TYPE_OBJECT
|
|
array[size] = null;
|
|
#endif
|
|
if(size != 0) ARRAYS.shiftDown(array, size, 0, comparator);
|
|
return value;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE peek(int index) {
|
|
if(index < 0 || index >= size) throw new NoSuchElementException();
|
|
return array[index];
|
|
}
|
|
|
|
@Override
|
|
public boolean removeFirst(KEY_TYPE e) {
|
|
for(int i = 0;i<size;i++)
|
|
if(KEY_EQUALS(e, array[i])) return removeIndex(i);
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean removeLast(KEY_TYPE e) {
|
|
for(int i = size-1;i>=0;i--)
|
|
if(KEY_EQUALS(e, array[i])) return removeIndex(i);
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
|
|
Objects.requireNonNull(action);
|
|
for(int i = 0,m=size;i<m;i++) action.accept(dequeue());
|
|
}
|
|
|
|
@Override
|
|
public <E> void forEach(E input, BI_OBJECT_CONSUMER KKS_GENERIC_TYPE<E> action) {
|
|
Objects.requireNonNull(action);
|
|
for(int i = 0,m=size;i<m;i++) action.accept(dequeue(), input);
|
|
}
|
|
|
|
@Override
|
|
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
for(int i = 0;i<size;i++) {
|
|
if(filter.TEST_VALUE(array[i])) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
for(int i = 0;i<size;i++) {
|
|
if(filter.TEST_VALUE(array[i])) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
for(int i = 0;i<size;i++) {
|
|
if(!filter.TEST_VALUE(array[i])) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
for(int i = 0;i<size;i++) {
|
|
if(filter.TEST_VALUE(array[i])) {
|
|
KEY_TYPE data = array[i];
|
|
removeIndex(i);
|
|
return data;
|
|
}
|
|
}
|
|
return EMPTY_VALUE;
|
|
}
|
|
|
|
protected boolean removeIndex(int index) {
|
|
array[index] = array[--size];
|
|
#if TYPE_OBJECT
|
|
array[size] = null;
|
|
#endif
|
|
if(size != index) ARRAYS.shiftDown(array, size, index, comparator);
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void onChanged() {
|
|
if(size <= 0) return;
|
|
ARRAYS.shiftDown(array, size, 0, comparator);
|
|
}
|
|
|
|
@Override
|
|
public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() {
|
|
return comparator;
|
|
}
|
|
|
|
@Override
|
|
public GENERIC_SPECIAL_KEY_BRACES<E> KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input) {
|
|
if(input == null || input.length < size()) input = NEW_SPECIAL_KEY_ARRAY(size());
|
|
System.arraycopy(array, 0, input, 0, size());
|
|
return input;
|
|
}
|
|
|
|
private class Iter implements ITERATOR KEY_GENERIC_TYPE {
|
|
@Override
|
|
public boolean hasNext() {
|
|
return !isEmpty();
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE NEXT() {
|
|
return dequeue();
|
|
}
|
|
}
|
|
} |