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

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

//MinHeap.hpp
#pragma once
#include <vector>
#include <iostream>
//模板最小堆类,要求T类内部重载比较运算符
template<typename T>
class MinHeap {
    
    
  public:
    //设定初始大小
    MinHeap(){
    
    };
    MinHeap(MinHeap<T>& minheap) {
    
     _heap(minheap); }
    MinHeap(MinHeap<T>&& minheap) {
    
     _heap(std::move(minheap)); }
    //添加元素
    void addItem(T& item) {
    
    
        int hole = getSize(); //新增元素在数组中的位置
        _heap.push_back(item);
        percolateUp(hole);
    }
    //删除元素
    //void eraseItem(std::shared_ptr<T> 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<T> _heap;
    
};

调用示例

	MinHeap<int> 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 

猜你喜欢

转载自blog.csdn.net/weixin_45685193/article/details/125857015