算法与数据结构——大顶堆 and 小顶堆
创始人
2024-12-16 13:06:05

0.定义

大顶堆:树中所有根节点必须大于等于其左儿子和右儿子,因此根节点是最大值。
小顶堆:树中所有根节点必须大于等于其左儿子和右儿子,因此根节点是最小值。

1.自己实现大顶堆和小顶堆

#pragma once  #include  #include  #include  using namespace std;   // 小顶堆 template  struct myGreater {     bool operator()(const T &left, const T &right) { return left > right; } };  // 大顶堆 template  struct myLess {     bool operator()(const T &left, const T &right) { return left < right; } };  template > class myHeap { public:     myHeap() {}      myHeap(vector vec)     {         _array.reserve(vec.size());         _array.assign(vec.begin(), vec.end());          // 建堆         for (int i = _array.size() / 2 - 1; i >= 0; i--)             AjustDown(i);     }      bool empty() const { return _array.empty(); }      size_t size() const { return _array.size(); }      T &top()     {         assert(!_array.empty());         return _array[0];     }      void push(T elem)     {         _array.push_back(elem);         AjustUp(_array.size() - 1);     }      void pop()     {         assert(!_array.empty());         swap(_array[0], _array[_array.size() - 1]);         _array.pop_back();         AjustDown(0);     }  private:     void AjustDown(int parent)     {         int child = parent * 2 + 1; // left child idx         while (child < _array.size())         {             if (child + 1 < _array.size() && cmp(_array[child], _array[child + 1]))                 ++child;              if (cmp(_array[parent], _array[child]))             {                 swap(_array[parent], _array[child]);                 parent = child;                 child = 2 * parent + 1;             }             else                 break;         }     }      void AjustUp(int child)     {         int parent = (child - 1) / 2;         while (parent >= 0)         {             if (cmp(_array[parent], _array[child]))             {                 swap(_array[parent], _array[child]);                 child = parent;                 parent = (child - 1) / 2;             }             else                 break;         }     }      vector _array;     Compare cmp; };  template  using maxHeap = myHeap>;  template  using minHeap = myHeap>;   int main() {     vector a = {11, 10, 13, 12, 16, 18, 15, 17, 14, 19};     myHeap hp1(a);      cout << hp1.top() << endl;     hp1.push(90);     hp1.push(900);     cout << hp1.top() << endl;     hp1.pop();     hp1.pop();     hp1.pop();     hp1.pop();     hp1.pop();     hp1.pop();     hp1.pop();      // system("pause");     return 0; }  

比较重要的是:

  1. 仿函数的写法:大顶堆是leftright,命名为Greater。
  2. 堆调整是cmp(_array[parent], _array[child])或者cmp(_array[left_child], _array[right_child]),这个顺序是和第一步仿函数的写法对应。这个过程详细描述如下:(以Less为例),Less是left 第一步,进行左孩子取值 < 右孩子取值比较,如果为真,使用右孩子与父节点比较,否则使用做孩子与父节点比较(见 AjustDown 函数体内 while 循环后第一个 if 语句);
    第二步,在父节点取值 < 孩子节点取值时,交换父和子,于是取值较大的孩子节点成为根节点(也就是说这个堆是大顶堆)。

2.STL优先队列

给自己打个广告:找工作准备刷题day1 栈与队列

优先队列练手:Leetcode347.前K个高频元素

自己写完以后更好地理解 为什么 小顶堆 的仿函数 是 >

相关内容

热门资讯

“无人家务”渐行渐近 记者 李 均 宋迎迎 从AI技术的持续突破,到各类AI产品与智能终端的加速落地,再到智慧生活场景的日...
苏州工业园区 2026年防灾减... 在第18个全国防灾减灾日到来之际,5月11日,苏州工业园区2026年防灾减灾宣传周启动仪式暨AI赋能...
【好物】雅诗兰黛第7代小棕瓶京... 全网 618 大促现已正式开始,全场均年度好价,有需求的小伙伴速抢哦: 京东无门槛红包 京东无门槛...
原创 1... 2011年4月底,郴州开往湖北的火车上,一名少年满头大汗地捂着腰部,低声呻吟。列车员和周围乘客焦急地...
Geekom Air12 20... 随着中国制造商在紧凑且高性能迷你电脑领域的崛起,Geekom已成为备受瞩目的品牌之一。此前,其AMD...