Algo Algo   C++   C#   Demo   JS   Py   SQL   Stat   TA

Structure : Binary Heap : Priority Queue

A heap data structure that takes the form of a binary tree and implements a priority queue. O(n) preprocessing O(log n) insert / extract min

// -----------------------------------------------------------------------------
// Binary Heap PQ                                                             C#
// -----------------------------------------------------------------------------

class BinaryHeapPQ<T> where T : IComparable
{
    int n = 0;
    T[] que = null;

    public BinaryHeapPQ() : this(1) { }

    public BinaryHeapPQ(int capacity)
    {
        que = new T[capacity + 1];
        n = 0;
    }

    public BinaryHeapPQ(T[] a)
    {
        n = a.Length;
        que = new T[n + 1];
        for (int i = 0; i < n; i++) que[i + 1] = a[i];
        for (int i = n / 2; i >= 1; i--) Sink(i);
    }

    public int Count { get { return n; } }

    public T Min { get { return que[1]; } }

    public void Insert(T x)
    {
        if (n == que.Length - 1) Resize(que.Length * 2);
        que[++n] = x;
        Swim(n);
    }

    public T ExtractMin()
    {
        Swap(1, n);
        T min = que[n--];
        Sink(1);
        que[n + 1] = default(T);
        return min;
    }

    void Swim(int k)
    {
        while (k > 1 && que[k / 2].CompareTo(que[k]) > 0) {
            Swap(k, k / 2);
            k = k / 2;
        }
    }

    void Sink(int k)
    {
        while (2 * k <= n) {
            int j = 2 * k;
            if (j < n && que[j].CompareTo(que[j + 1]) > 0) j++;
            if (que[k].CompareTo(que[j]) <= 0) break;
            Swap(k, j);
            k = j;
        }
    }

    void Resize(int capacity)
    {
        T[] temp = new T[capacity + 1];
        for (int i = 1; i <= n; i++) temp[i] = que[i];
        que = temp;
    }

    void Swap(int i, int j)
    {
        T temp = que[i];
        que[i] = que[j];
        que[j] = temp;
    }
}

// -----------------------------------------------------------------------------

Indexed Priority Queue

// -----------------------------------------------------------------------------
// Index Binary Heap PQ                                                       C#
// -----------------------------------------------------------------------------

class IndexBinaryHeapPQ<T> where T : IComparable
{
    int maxN = 0;
    int n = 0;
    int[] pq = null;
    int[] qp = null;
    T[] keys = null;

    public IndexBinaryHeapPQ(int maxN)
    {
        this.maxN = maxN;
        n = 0;
        keys = new T[maxN + 1];
        pq = new int[maxN + 1];
        qp = new int[maxN + 1];
        for (int i = 0; i <= maxN; i++) qp[i] = -1;
    }

    public int Count { get { return n; } }
    public bool Contains(int ix) { return qp[ix] != -1; }
    public T KeyOf(int ix) { return keys[ix]; }
    public int MinIndex { get { return pq[1]; } }
    public T MinKey { get { return keys[pq[1]]; } }

    public bool Insert(int ix, T key)
    {
        if (Contains(ix)) return false;
        n++;
        qp[ix] = n;
        pq[n] = ix;
        keys[ix] = key;
        Swim(n);
        return true;
    }

    public bool Change(int ix, T key)
    {
        if (!Contains(ix)) return false;
        keys[ix] = key;
        Swim(qp[ix]);
        Sink(qp[ix]);
        return true;
    }

    public bool Increase(int ix, T key)
    {
        if (!Contains(ix)) return false;
        if (keys[ix].CompareTo(key) >= 0) return false;
        keys[ix] = key;
        Sink(qp[ix]);
        return true;
    }

    public bool Decrease(int ix, T key)
    {
        if (!Contains(ix)) return false;
        if (keys[ix].CompareTo(key) <= 0) return false;
        keys[ix] = key;
        Swim(qp[ix]);
        return true;
    }

    public bool Remove(int ix)
    {
        if (!Contains(ix)) return false;
        int index = qp[ix];
        Swap(index, n--);
        Swim(index);
        Sink(index);
        keys[ix] = default(T);
        qp[ix] = -1;
        return true;
    }

    public int ExtractMin()
    {
        int min = pq[1];
        Swap(1, n--);
        Sink(1);
        qp[min] = -1;
        keys[min] = default(T);
        pq[n + 1] = -1;
        return min;
    }

    void Swim(int k)
    {
        while (k > 1 && keys[pq[k / 2]].CompareTo(keys[pq[k]]) > 0) {
            Swap(k, k / 2);
            k = k / 2;
        }
    }

    void Sink(int k)
    {
        while (2 * k <= n) {
            int j = 2 * k;
            if (j < n && keys[pq[j]].CompareTo(keys[pq[j + 1]]) > 0) j++;
            if (keys[pq[k]].CompareTo(keys[pq[j]]) <= 0) break;
            Swap(k, j);
            k = j;
        }
    }

    void Swap(int i, int j)
    {
        int swap = pq[i];
        pq[i] = pq[j];
        pq[j] = swap;
        qp[pq[i]] = i;
        qp[pq[j]] = j;
    }
}

// -----------------------------------------------------------------------------
Algo Algo   C++   C#   Demo   JS   Py   SQL   Stat   TA