This article assumes that you have a basic understanding of the algorithm for heap sorting.
The best way to analyze the source code of the heap in STL is to compare it with the common codes. Don't say much, first look at a regular heap sort of code:
//Adjust the large top pile, make the structure reasonablevoid Max_heap (intA[],intNodeint size){intLg=node;intL=node * *;intR=node * *+1;if(l<=size&&a[lg]<a[l]) {lg=l; }if(r<=size&&a[lg]<a[r]) {lg=r; }if(Lg!=node) {//a[lg]=a[lg]^a[node];//Exchange //a[node]=a[lg]^a[node]; //a[lg]=a[lg]^a[node]; intTT=A[LG]; A[lg]=a[node]; A[node]=tt; Max_heap (A,LG,size); }}//Generate a large top heapvoid Make_heap (intA[],int size){ for(intI=size/2;i>0; i--) {Max_heap (a,i,size); }}//heap sorting, which arranges the data in the array in order from small to largevoid Heap_sort (intA[],int size) {Make_heap (A,size); for(intI=1;i<size; i++) {inttt=a[1]; a[1]=a[size-i+1]; a[size-i+1]=tt; Max_heap (A,1,size-I.); }}
corresponding to the first function max_heap (), the STL has a function similar to Adjust_heap (), but also to adjust the entire heap to meet the requirements of the large top heap, the code is as follows:
// ============================================================================//Keep the nature of the heap//The entire process starts with the root node, swapping the maximum value in the root node and its child nodes until the leaf node (called the trace)then, starting from this root node, compare it to its parent node, and if it is larger than the parent node, the parent-child node is swapped until the root node (called upstream)//============================================================================//First start position//Holeindex where to adjust the operation//Len length//value holeindex the new settingTemplate<class_randomaccessiterator,class_distance,class_tp>void__adjust_heap (_randomaccessiterator __first, _distance __holeindex, _distance __len, _Tp __value) {//The index value of the current root node_distance __topindex = __holeindex;//Right child node index value_distance __secondchild =2* __holeindex +2;//If not to the end while(__secondchild < __len) {//If the value of the right child node is smaller than the value of the left child node, then secondchild points to the left child if(* (__first + __secondchild) < * (__first + (__secondchild-1))) __secondchild--;//Sub-node upward* (__first + __holeindex) = * (__first + __secondchild);//Continue processing__holeindex = __secondchild; __secondchild =2* (__secondchild +1); }//If there is no right child node if(__secondchild = = __len) {* (__first + __holeindex) = * (__first + (__secondchild-1)); __holeindex = __secondchild-1; }//Call Push_heap operation for node TopIndex__push_heap (__first, __holeindex, __topindex, __value);}//Upstream__push_heap (_randomaccessiterator __first, _distance __holeindex, _distance __topindex, _Tp __value) {//Gets the index value of the parent node_distance __parent = (__holeindex-1) /2;//If it has not risen to the root node and the value of the parent node is less than the value of the node to be inserted while(__holeindex > __topindex && * (__first + __parent) < __value) {//parent node drops to Holeindex* (__first + __holeindex) = * (__first + __parent);//Continue to check up__holeindex = __parent; __parent = (__holeindex-1) /2; }//Insert node* (__first + __holeindex) = __value;}
STL algorithm in the heap of the main process of adjustment, as noted in the note, the main is the first to go back to the leaf node, and then the push_heap with the upstream only to increase the completion. Compared to the normal code before, there are 3 major changes:
The recursive operation of ordinary code becomes a cyclic operation. This is a good understanding, because recursion requires the system to use resources to maintain the recursive stack, the cost is relatively large, so in addition to the sort in the STL (because the recursive depth of the fast row is limited), the recursive algorithm will generally be converted to a loop to do.
In normal code, we directly compare the values of the root node and the left and right nodes, and then exchange the nodes directly with the larger nodes if necessary, so that the tree can be adjusted only from the top to the next comparison. and the STL code, you have to go back, and then upstream, two times to complete the adjustment, it seems to be less efficient, why? I carefully analyzed the code, I feel there may be a reason for two points: 1. Code reuse, because the main function of the following is to ensure the nature of the big top heap, let the node to be adjusted from the root node sink, resulting in a new insertion node illusion, and Push_heap () It is in response to a new insertion node that a letter 2 is written, which re-uses this piece of code. 2. A little improvement in efficiency, because the next process requires only two sub-nodes of a comparison and the root node of the first assignment, and the upstream process only need to be compared with the root node once and the child nodes of the assignment, so the combination is actually two assignments and two comparisons, and in normal code, if the boundary check is not considered, Finding the maximum value in three points and exchanging it with it will require at least two comparisons and three assignments, so in STL's algorithm, the assignment operation is reduced once and the efficiency is improved.
In normal code, the left Dial hand node and the right child node are checked every time, while the STL code only bounds check the right child node, in order to prevent the right child node from crossing the boundary and the left child node is not out of bounds, the boundary check of the left Dial hand node is increased after the loop is finished. This modification significantly reduces the number of boundary checks and significantly increases efficiency.
Through the above analysis, in fact, we can also sprat. In fact, in the STL, there are a lot of such optimization, recursive cycle, reduce boundary check, with assignment instead of exchange, and so on, if we can study carefully, and in peacetime coding also develop such habits, can greatly improve the efficiency of the Code.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
STL Heap Part source code Analysis