C++ implementation of binary heap

A heap is a binary tree that is completely filled. The possible exception is at the bottom layer, where the elements on the bottom layer are filled from left to right. Such a tree is called a complete binary tree . The height of the complete binary tree is rounded down to logN. In the heap, for each node X, the key in X's parent is less than (or equal to) the key in X, except for the root node.
Heap insertion operation : To insert an element into the heap, a cavity is created at the next available position. If the inserted element can be put into the cavity without destroying the order of the heap, the insertion is complete. Otherwise, move the element on the parent node of the hole into the hole, so that the hole will take a step toward the root, and continue the process until the element can be put into the hole. This general strategy is called filtering .
Delete the smallest element of the heap : When deleting a smallest element, create a hole at the root node. Since the current heap is missing one element, the last element in the heap must be moved somewhere in the heap. If the last element can be placed in the cavity, then delete the smallest element to complete. Otherwise, move the smaller of the two children of the cavity into the cavity, thus pushing the cavity down one level, and repeat this step until the last element can be placed in the cavity. This is equivalent to placing the last element in the correct position along a path that contains the smallest son from the root. This general strategy is called down-filtering .

#ifndef BINARY_HEAP_H
#define BINARY_HEAP_H

#include "dsexceptions.h"
#include <vector>

using namespace std;

template <typename Comparable>
class BinaryHeap
{
    
    
public:
    explicit BinaryHeap(int capacity = 100)
     : array(capacity + 1), currentSize{
    
     0 } {
    
    }

    explicit BinaryHeap(const vector<Comparable> & items)
     : array(items.size() + 10), currentSize{
    
     items.size() }
    {
    
    
        for (int i = 0; i < items.size(); ++i)
            array[i + 1] = items[i];
        buildHeap();
    }

    bool isEmpty() const
    {
    
    
        return currentSize == 0;
    }

    const Comparable & findMin() const
    {
    
    
        if (isEmpty())
            throw UnderflowException{
    
    };
        return array[1];
    }

    void insert(const Comparable & x)
    {
    
    
        if (currentSize == array.size() - 1)
            array.resize(array.size() * 2);
        int hole = ++currentSize;
        Comparable copy = x;
        array[0] = std::move(copy);
        for (; x < array[hole / 2]; hole /= 2)
            array[hole] = std::move(array[hole / 2]);
        array[hole] = std::move(array[0]);
    }

    void insert(Comparable && x)
    {
    
    
        if (currentSize == array.size() - 1)
            array.resize(array.size() * 2);
        int hole = ++currentSize;
        Comparable copy = x;
        array[0] = std::move(copy);
        for (; hole > 1 && x < array[hole / 2]; hole /= 2)
            array[hole] = std::move(array[hole / 2]);
        array[hole] = std::move(x);
    }

    void deleteMin()
    {
    
    
        if (isEmpty())
            throw UnderflowException{
    
    };
        array[1] = std::move(array[currentSize--]);
        percolateDown(1);
    }

    void deleteMin(Comparable & minItem)
    {
    
    
        if (isEmpty())
            throw UnderflowException{
    
    };
        minItem = std::move(array[1]);
        array[1] = std::move(array[currentSize--]);
        percolateDown(1);
    }

    void makeEmpty()
    {
    
    
        currentSize = 0;
    }

private:
    int currentSize;
    vector<Comparable> array;
    void buildHeap()
    {
    
    
        for (int i = currentSize / 2; i > 0; --i)
            percolateDown(i);
    }

    void percolateDown(int hole)
    {
    
    
        int child;
        Comparable tmp = std::move(array[hole]);
        for (; hole * 2 <= currentSize; hole = child) {
    
    
            child = hole * 2;
            if (child != currentSize && array[child + 1] < array[child])
                ++child;
            if (array[child] < tmp)
                array[hole] = std::move(array[child]);
            else
                break;
        }
        array[hole] = std::move(tmp);
    }
};

#endif

Guess you like

Origin blog.csdn.net/qq_18431031/article/details/107753512