首页 > 代码库 > 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实现
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。