shz.PQueue Maven / Gradle / Ivy
package shz;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Objects;
@SuppressWarnings("unchecked")
public class PQueue {
protected E[] queue;
protected int size;
protected final Comparator super E> comparator;
protected PQueue(int capacity, Comparator super E> comparator) {
Validator.requireNon(capacity < 1);
Objects.requireNonNull(comparator);
queue = (E[]) new Object[capacity];
this.comparator = comparator;
}
public static PQueue of(int capacity, Comparator super E> comparator) {
return new PQueue<>(capacity, comparator);
}
public static PQueue of(Comparator super E> comparator) {
return of(16, comparator);
}
public final int size() {
return size;
}
public final boolean isEmpty() {
return size == 0;
}
public final void offer(E e) {
int i = size;
if (i >= queue.length) grow(i + 1);
size = i + 1;
if (i == 0) queue[0] = e;
else siftUp(i, e);
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) {
int oldCapacity = queue.length;
int newCapacity = oldCapacity + (oldCapacity < 64 ? oldCapacity + 2 : oldCapacity >> 1);
if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity);
queue = Arrays.copyOf(queue, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) throw new OutOfMemoryError();
return minCapacity > MAX_ARRAY_SIZE ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}
private void siftUp(int k, E x) {
while (k > 0) {
int parent = (k - 1) >>> 1;
E e = queue[parent];
if (comparator.compare(x, e) > 0) break;
queue[k] = e;
k = parent;
}
queue[k] = x;
}
public final E poll() {
if (size == 0) return null;
int s = --size;
E result = queue[0];
E x = queue[s];
queue[s] = null;
if (s != 0) siftDown(0, x);
return result;
}
private void siftDown(int k, E x) {
int half = size >>> 1;
while (k < half) {
int child = (k << 1) + 1;
E c = queue[child];
int right = child + 1;
if (right < size && comparator.compare(c, queue[right]) > 0) c = queue[child = right];
if (comparator.compare(x, c) < 0) break;
queue[k] = c;
k = child;
}
queue[k] = x;
}
public final E peek() {
return size == 0 ? null : queue[0];
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy