C++11 二叉堆

  二叉堆是一种特殊的堆,二叉堆是完全二元树(二叉树)或者是近似完全二元树(二叉树)。

  二叉堆有两种:大顶堆和小顶堆。

  大顶堆:父结点的键值总是大于或等于任何一个子节点的键值。

  小顶堆:父结点的键值总是小于或等于任何一个子节点的键值。

应用之一:参考 c++ priority_queue

下面举例子来看看一个二叉堆插入数据的例子(最小堆,即queue里面的小顶堆:greater)

#include <array>
#include <vector>
#include <iostream>


//二叉堆应用场景:优先队列,每次插入的时候,保证最小的值永远在最顶端,最小的出列消耗O(1)
//如:线程task,最小的task线程单元优先迅速执行完

//插入使用的二叉堆结构,最坏的情况O(log(N))
//采用顺序队列,插入每次的比较最坏情况O(N)


//根节点小于左右子节点  二叉堆
std::vector<int> vecInt{ 0,13,21,16,24,31,19,68,65,26,32};

//插入,保证堆根节点小于左右子节点。
int insert(const int x)
{
    //使用数组构造二叉堆,数组0的位置不计入,从1开始,满足左子index=2*index,右子index=2*index+1
    //当前堆大小设置为数组大小减一
    auto currentSize = vecInt.size() - 1;

    //需要加入新节点,扩容
    if (currentSize == vecInt.size() - 1)
    {
        vecInt.resize(vecInt.size() * 2);
    }

    //确定需要插入的起始位置,数组的最后一个位置,即树的第一个空的叶子节点
    auto hole = ++currentSize;

    //开始按层往上遍历,直到大于父节点
    for (; x < vecInt.at(hole / 2); hole /= 2)
    {
        //当前节点的值填充为父节点的值,即将父节点的值往下挪,将合适的hole位置空出来
        vecInt.at(hole) = std::move(vecInt.at(hole/2));
    }

    //找到hole位置后,放入要插入的x
    vecInt.at(hole) = x;

    return 0;
}


int printBinaryHeapByLevel()
{
    for (auto itor = vecInt.begin(); itor != vecInt.end(); itor++)
    {
        std::cout << *itor << ",";
    }
    std::cout << std::endl;

    return 0;
}


int main()
{
    std::cout << "before insert 14:" << std::endl;
    printBinaryHeapByLevel();
    
    insert(14);

    std::cout << "after insert 14:" << std::endl;
    printBinaryHeapByLevel();

    return 0;
}

输出:

原文地址:https://www.cnblogs.com/leehm/p/12930566.html