push_heap 源码剖析

来源:互联网 发布:asp.net购物车源码 编辑:程序博客网 时间:2024/06/06 06:45

一:用法示例

一共两个重载:

default (1)   
template <class RandomAccessIterator>
  void push_heap ( RandomAccessIterator first ,  RandomAccessIterator last ) ;
custom (2)   
template <class RandomAccessIterator, class Compare>
  void push_heap ( RandomAccessIterator first ,  RandomAccessIterator last , Compare comp ) ;

在说明这个函数的功能之前,我们先来看看对它的英文解释:

Push element into heap range
Given a heap in the range [first,last-1), this function extends the range considered a heap to[first,last) by placing the value in(last-1) into its corresponding location within it.

大概意思是,push_heap的作用范围是[ first , last),在使用push_heap必须保证[ first , last-1)满足堆,而*(last-1)是新增在末尾的一个值,那么此时对于整个[ first , last ) , 因为*(last-1)的新增可能已经不满足堆。push_back的作用就是重新调整*(last-1)的位置,使其整个[ first , last )满足堆。

例子:

#include<iostream>#include<functional>#include<algorithm>#include<vector>using namespace std;int main(){int a[10] = { 2,1,6,4,9,10,3,5,8,7 };vector<int> v(a, a + 10);sort(v.begin(), v.end());//现在是一个小顶堆v.push_back(-1);//现在在末尾插入一个-1,是整个数组的最小值push_heap(v.begin(), v.end(), greater<>());//现在-1已经在头部位置for (auto it = v.begin(); it != v.end(); it++)cout << *it << " ";//-1 1 3 4 2 6 7 8 9 10 5 cout << endl;return 0;}


二:源码及剖析

源码方面的话,其实一点都不难,一共4个模板函数,重点是第一个,其余三个都是基于第一个模板函数的。

// TEMPLATE FUNCTION push_heap WITH PREDtemplate<class _RanIt,class _Diff,class _Ty,class _Pr> inlinevoid _Push_heap(_RanIt _First, _Diff _Hole,_Diff _Top, _Ty&& _Val, _Pr _Pred){// percolate _Hole to _Top or where _Val belongs, using _Predfor (_Diff _Idx = (_Hole - 1) / 2;_Top < _Hole && _DEBUG_LT_PRED(_Pred, *(_First + _Idx), _Val);_Idx = (_Hole - 1) / 2){// move _Hole up to parent*(_First + _Hole) = _STD move(*(_First + _Idx));_Hole = _Idx;}/*_Top < _Hole是对边界的判断;_DEBUG_LT_PRED(_Pred, *(_First + _Idx), _Val)相当于_Pred(*(_First + _Idx), _Val)*/*(_First + _Hole) = _STD move(_Val);// drop _Val into final hole}template<class _RanIt,class _Diff,class _Ty,class _Pr> inlinevoid _Push_heap_0(_RanIt _First, _RanIt _Last, _Pr _Pred, _Diff *, _Ty *){// push *_Last onto heap at [_First, _Last), using _Pred_Diff _Count = _Last - _First;if (0 < _Count){// worth doing, percolate *_Last_Ty _Val = _STD move(*_Last);_Push_heap(_First, _Count, _Diff(0), _STD move(_Val), _Pred);}}template<class _RanIt,class _Pr> inlinevoid push_heap(_RanIt _First, _RanIt _Last, _Pr _Pred){// push *(_Last - 1) onto heap at [_First, _Last - 1), using _Pred_DEBUG_RANGE_PTR(_First, _Last, _Pred);if (_First != _Last){// check and push to nontrivial heap--_Last;_DEBUG_HEAP_PRED(_First, _Last, _Pred);_Push_heap_0(_Unchecked(_First), _Unchecked(_Last), _Pred,_Dist_type(_First), _Val_type(_First));}}// TEMPLATE FUNCTION push_heaptemplate<class _RanIt> inlinevoid push_heap(_RanIt _First, _RanIt _Last){// push *(_Last - 1) onto heap at [_First, _Last - 1), using operator<_STD push_heap(_First, _Last, less<>());}

源码摘抄自Visual Studio 2015安装目录algorithm文件中。



点击进入目录----> C++源码剖析目录










0 0