数据结构:堆(Heap)

堆的代码实现和注释


#pragma once

#include<iostream>
#include<vector>
#include<assert.h>
using namespace std;
//小根堆
template<class T>
struct Less{
    bool operator()(const T& l,const T& r){
        return l<r;
    }
};
//大根堆
template<class T>
struct Larger{
    bool operator()(const T& l,const T& r){
        return l>r;
    }
};
//堆模板接口<类型,比较函数>
template<class T,class compare=Larger<T>>
class Heap
{
public:
    Heap(){}
    Heap(T* a,size_t size)
    {
        _a.reserve(size);   //容器预留空间,但并不真正创建元素对象
        for(size_t i=0;i<size;++i){
            _a.push_back(a[i]);
        }
        //建堆,从第一个非叶子节点的父节点开始调整
        for(int i=(size-2)/2;i>=0;i--){
            AdjustDown(i);        //向下调整
        }
    }

    void Push(const T& d){
        _a.push_back(d);
        AdjustUp(_a.size()-1);
    }

    void Pop(){
        assert(!_a.empty());
        swap(_a[0],_a[_a.size()-1]);
        _a.pop_back();
        AdjustDown(0);
    }
    const T& Top()
    {
        assert(!_a.empty());
        return _a[0];
    }

    bool Empty()
    {
        return _a.empty();
    }

    size_t Size(){
        return _a.size();
    }
    //打印一维数组
    void Print(){
        for(size_t i=0 ;i<_a.size();++i){
            cout<< _a[i]<<" ";
        }
        cout << endl;
    }



protected:
    void AdjustDown(size_t root){
        compare com;
        size_t parent = root;
        size_t child = parent*2+1; //lchild 指向左孩子
        while(child<_a.size()){
            //保证右孩子不为空,比较左右孩子
            if(child+1<_a.size() && com(_a[child+1],_a[child]))
            {
                ++child;
            }
            //将parent与child交换,并向下更新child位置
            if(com(_a[child],_a[parent]))
            {
                std::swap(_a[parent],_a[child]);
                parent = child;
                child = parent*2+1;
            }
            else
                break;
            
        }
    }

    void AdjustUp(size_t child){
        while(child>0){
            compare com;
            size_t parent = (child-1)/2;
            if(com(_a[child],_a[parent])){
                std::swap(_a[parent],_a[child]);
                child = parent;
            }
            else
                break;
        }
    }    
protected:
    vector<T> _a;
};


























posted @ 2019-03-25 10:48  Coder_L  阅读(240)  评论(0编辑  收藏  举报