二叉堆是一种特殊的堆,二叉堆是完全二元树(二叉树)或者是近似完全二元树(二叉树)。
二叉堆有两种:大顶堆和小顶堆。
大顶堆:父结点的键值总是大于或等于任何一个子节点的键值。
小顶堆:父结点的键值总是小于或等于任何一个子节点的键值。
应用之一:参考 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; }
输出: