【Data Structure】Heap

What is a heap?

  The heap here does not refer to the "stack" in the computer, but refers to a data structure whose structure is a binary tree.
We store all elements in a key set in a one-dimensional array in the order of a complete binary tree, and satisfy one of the following two:

  • The key of any node is less than or equal to the key of its left and right children, and the smallest key at the top of the heap is called the min heap;
  • The key of any node is greater than or equal to the key of its left and right children, and the key at the top of the heap is called the maximum heap.

heap creation

This creates a min heap:
write picture description here

Heap insertion and deletion

Because each insertion of the heap is inserted after the minimum heap that has been built, but after the insertion, the heap needs to be adjusted from the bottom up.
write picture description here
Heap Deletion: Removes the top element from the top of the heap. After removing the top element of the heap, fill the top element with the last node of the heap, and reduce the number of elements by one, and adjust the heap from top to bottom.
write picture description here

heap application

  1. Priority queue: The underlying implementation of a priority queue is the heap.
  2. Find the largest top K in a pile of data: first create the top K data as a small heap, and then traverse the data to be found in turn. If the data is larger than the top element of the heap, replace the top element with it, and replace the top element with it. Heap adjustment so that you end up with the largest K elements.
  3. Heap sort: If it is ascending order, we need to create a large heap, using the idea similar to deleting elements, we swap the top element of the heap with the last one and then adjust the heap, and finally we can get an ascending sequence; otherwise, sort in descending order , a small heap is created.

Here is the code implementation:

#include <iostream>
#include <vector>
using namespace std;

template <class T>
struct Less//小堆
{
    bool operator()(const T& left, const T& right)
    {
        return left->_data < right->_data;
    }
}; 

template <class T>
struct Greater//大堆
{
    bool operator()(const T& left, const T& right)
    {
        return left > right;
    }
};

template <class T, class Compare = Less<T>>
class Heap
{
public:
    Heap()
    {}
    Heap(T *arr, size_t size)
    {
        _arr.resize(size);
        for (size_t i = 0; i < size; i++)
            _arr[i] = arr[i];
        if (size > 1)
        {
            int root = (size - 2) / 2;//size_t的数据大于等于0造成死循环
            for (; root >= 0; root--)
                _AdjustDown(root);
        }
    }

    void Push(const T& data)
    {
        _arr.push_back(data);
        size_t size = _arr.size();
        if (size > 1)
            _AdjustUp(size - 1);
    }

    void Pop()
    {
        size_t size = _arr.size();
        if (_arr.empty())
            return;
        swap(_arr[0], _arr[size - 1]);
        _arr.pop_back();
        if (_arr.size() > 1)
            _AdjustDown(0);
    }

    bool Empty()const
    {
        return _arr.empty();
    }

    size_t Size()const
    {
        return _arr.size();
    }

    T Top()const
    {
        return _arr[0];
    }

private:
    void _AdjustDown(size_t parent)
    {
        size_t child = parent * 2 + 1;
        size_t size = _arr.size();
        while (child < size)
        {
            if (child + 1 < size && Compare()(_arr[child + 1], _arr[child]))
                child += 1;
            if (Compare()(_arr[child], _arr[parent]))
            {
                swap(_arr[parent], _arr[child]);
                parent = child;
                child = parent * 2 + 1;
            }
            else
                break;
        }
    }

    void _AdjustUp(size_t child)
    {
        size_t parent = (child - 1) / 2;
        size_t size = _arr.size();
        while (child > 0)
        {
            if (Compare()(_arr[child], _arr[parent]))
            {
                swap(_arr[parent], _arr[child]);
                child = parent;
                parent = (child - 1) / 2;
            }
            else
                break;
        }
    }
private:
    vector<T> _arr;
};

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325627171&siteId=291194637