首页 > 代码库 > heap实现

heap实现

//STL提供的是Max heap,使用vector作为底部容器//push_heap算法:首先将元素放到堆所对应的数组的末端,然后从该节点开始向上调整,//若当前结点键值比父结点大,则兑换位置,如此一直上溯,直到不需对换或直到根节点为止template <class RandomAccessIterator>inline void push_heap(RandomAccessIterator first, RandomAccessIterator last){    //该函数被调用时,新元素已置于底部容器的最末端    _push_heap_aux(firsst, last, distance_type(first), value_type(first));}template <class RandomAccessIterator ,class Distance,class T>inline void _push_heap_aux(RandomAccessIterator first, RandomAccessIterator last, Distance*, T*){    _push_heap(first, Distance((last - first) - 1), Distance(0), T(*(last - 1)));}template <class RandomAccessIterator, class Distance, class T>//first是根节点的迭代器,holeIndex是当前结点下标,topIndex是根节点下标,value是要调整的元素的值void _push_heap(RandomAccessIterator first, Distance holeIndex, Distance topIndex, T value){    Distance parent = (holeIndex - 1);//父节点下标    while (holeIndex > topIndex&&*(first + parent) < value)    {        *(first + holeIndex) = *(first + parent);        holeIndex = parent;        parent = (holeIndex - 1) / 2;    }    *(first + holeIndex) = value;}//pop_heap算法:将最下层最右边的叶节点(即底层容器中最末端元素)替换根节点,然后向下调整//pop_heap后,最大元素只是被置放于底部容器的最尾端,尚未被取走template <class RandomAccessIterator ,class Distance,class T>//holeIndex初始化为0,是根节点的位置,本算法先一直向下调整到叶节点,然后可能需要向上调整//实际上没必要,只需要当当前结点比左右孩子结点的值都大时就可以停止调整了void _adjust_heap(RandomAccessIterator first, Distance holeIndex, Distance len, T value){    Distance topIndex = holeIndex;    Distance secondChild = 2 * holeIndex + 2;//右子结点    while (secondChild < len)    {        if (*(first + secondChild) < *(first + secondChild - 1))            secondChild--;        *(first + holeIndex) = *(first = secondChild);        holeIndex = secondChild;        secondChild = 2 * (secondChild + 1);    }    if (secondChild == len)//没有右子结点,只有左子结点    {        *(first + holeIndex) = *(first + secondChild - 1);        holeIndex = secondChild - 1;    }    _push_heap(first, holeIndex, topIndex, value);}//sort_heap算法:连续调用pop_heap即可//排序之后,原来的heap就不再符合heap的特征了template <class RandomAccessIterator>void sort_heap(RandomAccessIterator first, RandomAccessIterator last){    while (last - first > 1)        pop_heap(first, last--);}//make_heap算法:从最后一个非叶节点开始,每个非叶节点都向下调整template <class RandomAccessIterator,class T,class Distance>void _make_heap(RandomAccessIterator first, RandomAccessIterator last, T*, Distance*){    if (last - first < 2)        return;    Distance len = last - first;    Distance parent = (len - 2) / 2;    while (ture)    {        _adjust_heap(first, parent, len, T(*(first + parent)));        if (parent == 0)            return;        parent--;    }}

 

heap实现