STL source code profiling algorithm stl_heap.h
Heap
-------------------------------------------------------------------------
Binary heap is a Complete binary Tree.
Implicit representation: tree is expressed in array.
Tip: Keep the #0 element of array, and the left and right subnodes of element I are 2i and 2i + 1, respectively,
The parent node is I/2 --> STL does not use this trick.
Changing the size of an array cannot be changed dynamically. Therefore, use a vector instead of an array.
This file provides various heap Operation algorithms. Note that there is no heap class.
Figure 4-20
Example:
#include
#include
#include
#include using namespace std;void display(const vector
&v){copy(v.begin(), v.end(), ostream_iterator
(cout, ));cout << endl;}int main(){int ia[] = {0,1,2,3,4,8,9,3,5};vector
ivec(ia, ia + sizeof(ia)/sizeof(int));make_heap(ivec.begin(),ivec.end());display(ivec);ivec.push_back(7);push_heap(ivec.begin(), ivec.end());display(ivec);pop_heap(ivec.begin(), ivec.end());ivec.pop_back();display(ivec);sort_heap(ivec.begin(), ivec.end());display(ivec);}
Source code:
# Ifndef _ SGI_STL_INTERNAL_HEAP_H # define _ sgi_stl_internal_heap_h1_stl_begin_namespace # if defined (_ sgi )&&! Defined (_ GNUC _) & (_ MIPS_SIM! = _ MIPS_SIM_ABI32) # pragma set woff 1209 # endiftemplate
Void _ push_heap (RandomAccessIterator first, Distance holeIndex, Distance topIndex, T value) {Distance parent = (holeIndex-1)/2; // locate the parent node // when the node has not reached the top and the parent node is smaller than the new value (so it does not conform to the heap sequence feature) while (holeIndex> topIndex & * (first + parent) <value) {* (first + holeIndex) = * (first + parent); // set the hole value to the parent value holeIndex = parent; // adjust the hole number, upgrade to the parent node parent = (holeIndex-1)/2; // The parent node of the new hole} * (first + holeIndex) = value; // The value of the new hole is the new value, insert completed} template
Inline void _ push_heap_aux (RandomAccessIterator first, RandomAccessIterator last, Distance *, T *) {_ push_heap (first, Distance (last-first)-1 ), distance (0), T (* (last-1);}/* when this function is called, the new element should be placed at the tail end of the container at the bottom --> when will it be set? --> Stl_heap is not open to external users and is only used inside STL. Other STL programs using push_heap should note that the new element is placed at the tail end of the container at the bottom of heap before calling the push_heap function */template
Inline void push_heap (RandomAccessIterator first, RandomAccessIterator last) {_ push_heap_aux (first, last, distance_type (first), value_type (first);} template
Void _ push_heap (RandomAccessIterator first, Distance holeIndex, Distance topIndex, T value, Compare comp) {Distance parent = (holeIndex-1)/2; while (holeIndex> topIndex & comp (* (first + parent), value) {* (first + holeIndex) = * (first + parent); holeIndex = parent; parent = (holeIndex-1)/2;} * (first + holeIndex) = value;} // many of these function bodies in STL directly call the function of another function, it seems that this is not very good. It increases the overhead of the stack. // Why not call the function in it directly? template
Inline void _ push_heap_aux (RandomAccessIterator first, RandomAccessIterator last, Compare comp, Distance *, T *) {_ push_heap (first, Distance (last-first)-1 ), distance (0), T (* (last-1), comp);} template
Inline void push_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp) {_ push_heap_aux (first, last, comp, distance_type (first), value_type (first);} template
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);} template
Inline void _ pop_heap (random first, RandomAccessIterator last, RandomAccessIterator result, T value, Distance *) {* result = * first; _ adjust_heap (first, Distance (0 ), distance (last-first), value);} template
Inline void _ pop_heap_aux (RandomAccessIterator first, RandomAccessIterator last, T *) {// the result of the pop operation should be the first element of the container at the bottom _ pop_heap (first, last-1, last-1, T (* (last-1), distance_type (first);} template
Inline void pop_heap (RandomAccessIterator first, RandomAccessIterator last) {_ pop_heap_aux (first, last, value_type (first);} template
Void _ adjust_heap (RandomAccessIterator first, Distance holeIndex, Distance len, T value, Compare comp) {Distance topIndex = holeIndex; Distance secondChild = 2 * holeIndex + 2; // while (secondChild <len) {// if (comp (* (first + secondChild ), * (first + (secondChild-1) secondChild --; * (first + holeIndex) = * (first + secondChild ); // make the greater vertex value holeIndex = secondChild; // move the hole number down to secondChild = 2 * (secondChild + 1) at the larger subnode ); // find the child node of the new hole node} if (secondChild = len) {// when only the left node exists * (first + holeIndex) = * (first + (secondChild-1); holeIndex = secondChild-1;} _ push_heap (first, holeIndex, topIndex, value, comp);} template
Inline void _ pop_heap (RandomAccessIterator first, RandomAccessIterator last, RandomAccessIterator result, T value, Compare comp, Distance *) {// set the first value (that is, the value to pop) stored in the result. * Result = * first; // re-adjust heap. The hole number is 0. To adjust the value to value _ adjust_heap (first, Distance (0), Distance (last-first ), value, comp);} template
Inline void _ pop_heap_aux (RandomAccessIterator first, RandomAccessIterator last, T *, Compare comp) {_ pop_heap (first, last-1, last-1, T (* (last-1), comp, distance_type (first);} template
Inline void pop_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp) {_ pop_heap_aux (first, last, value_type (first), comp);} template
Void _ make_heap (RandomAccessIterator first, RandomAccessIterator last, T *, Distance *) {if (last-first <2) return; Distance len = last-first; distance parent = (len-2)/2; while (true) {_ adjust_heap (first, parent, len, T (* (first + parent ))); if (parent = 0) return; parent --;} template
Inline void make_heap (RandomAccessIterator first, RandomAccessIterator last) {_ make_heap (first, last, value_type (first), distance_type (first);} template
Void _ make_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp, T *, Distance *) {if (last-first <2) return; Distance len = last-first; // locate the header of the first subtree to be rearranged and mark it as a parent. Distance parent = (len-2)/2; while (true) {_ adjust_heap (first, parent, len, T (* (first + parent), comp ); if (parent = 0) return; // After the root node is completed, it is over. Parent --; // In fact, the value is adjusted from left to right along the first parent node so that the value of the parent node is greater than (or less than) Two subnodes} template
Inline void make_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp) {_ make_heap (first, last, comp, value_type (first), distance_type (first);} template
Void sort_heap (RandomAccessIterator first, RandomAccessIterator last) {// pop_heap () is executed each time, and the extreme value is placed at the end. // after the end is deducted, pop_heap () is executed again (), the next extreme value is placed at the new end. // The sorting result can be obtained. The result is while (last-first> 1) pop_heap (first, last --);} template.
Void sort_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp) {while (last-first> 1) pop_heap (first, last --, comp) ;}# if defined (_ sgi) &&! Defined (_ GNUC _) & (_ MIPS_SIM! = _ MIPS_SIM_ABI32) # pragma reset woff 1209 # endif _ STL_END_NAMESPACE # endif/* _ SGI_STL_INTERNAL_HEAP_H * // Local Variables: // mode: C ++/End: