堆(heap)在c++中的实现

     不少涉及最大最小值的算法都会用到堆(优先队列),今个做中位数的时候用到了堆,就整理下堆的用法及实现。

一. 堆

    在逻辑上可以看作是完全二叉树的一种,其特点是堆中某个结点的值总是不大于或不小于其父结点的值。最常用的于堆排序。堆排序优点在于能够快速获取最大(最小)的k个值。堆在存储上可以通过一维数组(优先队列)

来实现。

二.堆的操作

    堆的操作一般包括:查找顶元素,删除元素,插入元素。此外还包括堆排序

    一维数组表示的完全二叉树的以下特性可以帮助我们更快的调整堆

  • 索引为p的结点的左孩子的索引为p*2+ 1
  • 索引为p的结点的右孩子的索引为p *2+ 2
  • 索引为p的结点的父亲的索引为(p-1)/ 2 

查找:直接返回堆顶的值就行,即返回vector a[0],时间复杂度为O(1)。

删除:先用队尾的元素替换掉要删除的元素,然后从该元素的子结点中选择较大(较小)的值和其比较,循环往复,直到满足堆的性质。时间复杂度为O(logN)

复制代码
    h[i] = h[h.size() - 1];
    h.pop_back();
    while (i * 2 + 2 < h.size() && (h[i * 2 + 1] > h[i] || h[i * 2 + 2] > h[i])) {
        int w;
        if (h[i * 2 + 1] > h[i * 2 + 2])
            w = i * 2 + 1;
        else
            w = i * 2 + 2;
        int m = max(h[i * 2 + 1], h[i * 2 + 2]);
        int t = m;
        m = h[i];
        h[i] = t;
        i = w;
    }
    if (i * 2 + 1 < h.size() && h[i * 2 + 1] > h[i])
    {
        int t = h[i * 2 + 1];
        h[i*2+1] = h[i];
        h[i] = t;
    }
复制代码

插入:将元素插入到队尾,从下到上的调整堆就好。时间复杂度O(logn)

复制代码
        h.push_back(num);
        int l1=(h.size()+1)/2-1;
        int l2=h.size();
        while(l1>=0&&num<h[l1]){
            int t=h[l1];
            h[l1]=h[l2];
            h[l2]=t;
            l2=l1;
            l1=(l2+1)/2-1;
        }
复制代码

 

堆排序:按照数组的次序填入完全二叉树,再从倒数第一个不是叶子节点的节点开始,一个个地看是不是要向下调整,一直下调到不能再调。时间复杂度O(nlogn)

复制代码
void Adjust(int low,int high){
    int i = low;
    int j = i*2;
    while(j<=n){
        if(j+1<=n&&heap[j+1]>heap[j]){
            j = j+1;
        }
        if(heap[i]<heap[j]){
            swap(heap[i],heap[j]);
            i = j;
            j = i*2;
        }else break;
    }
}
复制代码

三.stl中的实现

    STL中定义的模板类为priority_queue,其定义如下,其中的排序操作可以通过重载运算符实现。

template <class T, class Container = vector<T>, class Compare = less<typename Container::value_type> >

  STL中的操作包括以下五个,其中并没有实现任意位置删除,而是只能删除堆顶的元素。

  • bool empty():如果优先队列为空返回 true,否则返回false。
  • int size():返回优先队列中元素数量。
  • void push(const T&. t):把t元素压入优先队列。
  • void pop():优先队列非空情况下,删除优先级最高元素。
  • T&. top():优先队列非空情况下,返回优先级最高元素的引用。

2023-03-20 21:06:48

 

posted @   颉颃胜负!  阅读(345)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示