栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ 最小堆模板类的实现

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ 最小堆模板类的实现

本来想直接用该模板类实现定时器的,发现与定时器事件耦合太多,编程能力不足想不到解耦合的办法,弃用又觉得可惜,在这代码贴出来吧。

//MinHeap.hpp
#pragma once
#include 
#include 
//模板最小堆类,要求T类内部重载比较运算符
template
class MinHeap {
  public:
    //设定初始大小
    MinHeap(){};
    MinHeap(MinHeap& minheap) { _heap(minheap); }
    MinHeap(MinHeap&& minheap) { _heap(std::move(minheap)); }
    //添加元素
    void addItem(T& item) {
        int hole = getSize(); //新增元素在数组中的位置
        _heap.push_back(item);
        percolateUp(hole);
    }
    //删除元素
    //void eraseItem(std::shared_ptr item) {}
    //获取最小元素
    T getMin() const {
        return _heap[0];
    }
    //删除最小元素
    void popMin() {
        if(isEmpty()) return;
        //将根节点的元素与最后一个元素互换,再将当前的根节点下沉即可
        std::swap(_heap[0], _heap[getSize() - 1]);
        _heap.pop_back(); // vector删除尾元素的时间复杂度是1
        if (!isEmpty()) {
            percolateDown(0);
        }
        
    }
    //是否为空
    inline bool isEmpty() { return _heap.empty(); }
    //最小堆大小
    inline int getSize() { return _heap.size(); }

    
  private:
    //将第hole个元素下虑,确保以第hole个结点作为根的子树拥有最小堆性质
    void percolateDown(int hole) {
        int child = 0;
        for (; (hole * 2 + 1) < getSize(); hole = child) {
            //左子节点
            child = hole * 2 + 1;
            //挑选一个较小的节点进行交换
            if (child < getSize() - 1 && (_heap[child + 1]) < (_heap[child])) {
                //此时右节点较小,切换到右节点
                child++;
            }
            if (_heap[child] < _heap[hole]) {
                std::swap(_heap[hole], _heap[child]);
            }
            else {
                break;
            }
        }
    }
    //将第hole个元素上浮
    void percolateUp(int hole) {
        int parent = 0;
        T tmp = _heap[hole];
        //上浮操作
        for (; hole > 0; hole = parent) {
            parent = (hole - 1) / 2;
            if (_heap[parent] > tmp) {
                //这里先不急着交换,在parent位置留下一个空穴
                _heap[hole] = _heap[parent];
            }
            else {
                break;
            }
        }
        _heap[hole] = tmp;
    }
  private:
    std::vector _heap;
    
};

调用示例

	MinHeap heap;
    int a = 1;
    heap.addItem(a);
    a = 3;
    heap.addItem(a);
    a = 5;
    heap.addItem(a);
    a = 6;
    heap.addItem(a);
    a = 2;
    heap.addItem(a);

    cout << endl;

    while (!heap.isEmpty()) {
        cout << heap.getMin()<< " " ;
        heap.popMin();
    }
    cout << endl;

输出

1 2 3 5 6 
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1019451.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号