All Downloads are FREE. Search and download functionalities are using the official Maven repository.

shz.core.queue.p.PQueue Maven / Gradle / Ivy

There is a newer version: 2024.0.2
Show newest version
package shz.core.queue.p;

import shz.core.NullHelp;

import java.io.*;
import java.util.Arrays;
import java.util.Comparator;

@SuppressWarnings("unchecked")
public final class PQueue implements Serializable {
    private static final long serialVersionUID = 3725082509315337576L;
    final int capacity;
    transient E[] queue;
    transient int size;
    final Comparator comparator;

    public PQueue(int capacity, Comparator comparator) {
        NullHelp.requireNon(capacity < 1);
        NullHelp.requireNonNull(comparator);
        this.capacity = capacity;
        this.comparator = comparator;
        queue = (E[]) new Object[capacity];
    }

    public PQueue(Comparator comparator) {
        this(16, comparator);
    }

    public static  PQueue of(int capacity, Comparator comparator) {
        return new PQueue<>(capacity, comparator);
    }

    public static  PQueue of(Comparator comparator) {
        return new PQueue<>(comparator);
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public 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 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 E peek() {
        return size == 0 ? null : queue[0];
    }

    private void writeObject(ObjectOutputStream oos) throws IOException {
        oos.defaultWriteObject();
    }

    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        ois.defaultReadObject();
        queue = (E[]) new Object[capacity];
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy