Binary HeapΒΆ

Warning

NOT TESTED

#include <iostream> // cout, endl
#include <cstring>  // memset

using namespace std;

#define      parent(x) (x/2)
#define  left_child(x) (2*x)
#define right_child(x) (2*x + 1)

class BinaryMinHeap {
public:
    int * heap;
    int size;
    int max_size;

    BinaryMinHeap(int s)
    {
        /*
            Obs: 0 is sentinel
            Complexity: O(1)
        */

        max_size = s + 1;
        size = 0;

        heap = new int[max_size];
        memset(heap, 0, max_size*sizeof(int));
    }

    void build(int * values, int n)
    {
        /*
            build: builds a heap from an array of values.
            Complexity: O(n log n)
        */
        for(int i = 0; i < n; i++)
            insert(values[i]);
    }

    void heapify(int values[], int n)
    {
        /*
            heapify: turns an array into a heap.
            Complexity: O(n log n)

            !!ATENTION!!
            * Remember to put the sentinel at 0 in the values array
            * The array `values` will be changed in the process
        */

        size = n;
        heap = values;

        for(int i = size/2; i >= 1; --i)
            shift_down(i);
    }

    void insert(int element)
    {
        /*
            insert: adds an element into the heap
            Complexity: O(log n)
        */

        // If the heap is full, there is nothing to be done
        if(size + 1 == max_size) return;

        size++;

        // Add the element to the heap
        heap[size] = element;

        // Rearrenge the heap considering the new element
        int parent_index = parent(size);
        int index = size;

        // While the new element is less the its parent, new element its not
        // the root
        while(index > 1 && heap[parent_index] > element)
        {
            heap[index] = heap[parent_index];
            heap[parent_index] = element;

            index = parent_index;
            parent_index = parent(parent_index);
        }
    }

    int extract_min()
    {
        /*
            extract_min: removes the root element from the heap
            Complexity: O(log n)
        */

        // if the heap is empty, return -1
        if(size == 0) return -1;

        // Pick the root element to extract
        int element = heap[1];

        // Put the last leaf in the root
        heap[1] = heap[size];
        size--;

        // Rearrenge the heap after remotion
        shift_down(1);

        return element;
    }

private:

    inline void shift_down(int index)
    {
        /*
            shift_down: moves the node down until it reachs a level where its
                        children have a lower priority than it has.
            Complexity: O(log n)
        */

        int lowest_child_index;
        int lowest_child;

        // While the node has children
        while(index <= size/2)
        {
            // If the node has lower priority than one of its children
            // swap the child with its parent

            lowest_child_index = get_lowest_child_index(index);
            lowest_child = heap[lowest_child_index];

            if(lowest_child > heap[index]) break;

            heap[lowest_child_index] = heap[index];
            heap[index] = lowest_child;

            index = lowest_child_index;
        }
    }

    inline int get_lowest_child_index(int index)
    {
        /*
            Complexity: O(1)
        */

        int lowest_child_index = left_child(index);

        if(right_child(index) <= size &&
          heap[left_child(index)] > heap[right_child(index)])
            lowest_child_index = right_child(index);

        return lowest_child_index;
    }

};

Usage:

BinaryMinHeap heap(10);

int values[] = {45, 2, 12, 8, 6, 23, 1, 6, 9, 10};

heap.build(values, 10);

heap.extract_min();

int values2[] = {0, 45, 2, 12, 8, 6, 23, 1, 6, 9, 10};

heap.heapify(values2, 10);

heap.insert(80);