STL source code profiling algorithm stl_algo.h -- inplace_merge
Inplace_merge (used in ordered intervals)
--------------------------------------------------------------------
Description: if the two connected sequences [first, middle) and [middle, last] are sorted,
Then inplace_merge can combine them into a single sequence, which is still ordered.
Source code:
Template
Inline void inplace_merge (BidirectionalIterator first, BidirectionalIterator middle, bidirealialiterator last) {if (first = middle | middle = last) return; // if any sequence is empty, you don't need to do anything. _ inplace_merge_aux (first, middle, last, value_type (first), distance_type (first);} // helper function template
Inline void _ inplace_merge_aux (BidirectionalIterator first, bidirealialiterator middle, bidirealialiterator last, T *, Distance *) {Distance len1 = 0; distance (first, middle, len1 ); distance len2 = 0; distance (middle, last, len2); // uses the extra memory space (temporary buffer) temporary_buffer
Buf (first, last); if (buf. begin () = 0) // memory allocation failed _ merge_without_buffer (first, middle, last, len1, len2 ); else // perform _ merge_adaptive (first, middle, last, len1, len2, buf. begin (), Distance (buf. size ();} // helper function. Template with buffer
Void _ merge_adaptive (invalid first, invalid middle, BidirectionalIterator last, Distance len1, Distance len2, Pointer buffer, Distance buffer_size) {if (len1 <= len2 & len1 <= buffer_size) {Pointer end_buffer = copy (first, middle, buffer); merge (buffer, end_buffer, middle, last, first);} else if (len2 <= buffer_size) {Pointer end_buffer = copy (middle, last, buffer); _ merge_backward (first, middle, buffer, end_buffer, last);} else {BidirectionalIterator first_cut = first; bidirectionalIterator second_cut = middle; Distance len11 = 0; Distance len22 = 0; if (len1> len2) {len11 = len1/2; advance (first_cut, len11 ); second_cut = lower_bound (middle, last, * first_cut); distance (middle, second_cut, len22);} else {len22 = len2/2; advance (second_cut, len22 ); first_cut = upper_bound (first, middle, * second_cut); distance (first, first_cut, len11);} specify partition = _ rotate_adaptive (first_cut, middle, second_cut, len1-len11, len22, buffer, buffer_size); _ merge_adaptive (first, first_cut, average, len11, len22, buffer, buffer_size); _ merge_adaptive (new_middle, second_cut, last, len1-len11, len2-len22, buffer, buffer_size );}}
Example:
int main(){ int A[] = { 1, 3, 5, 7, 2, 4, 6, 8 }; inplace_merge(A, A + 4, A + 8); copy(A, A + 8, ostream_iterator
(cout, )); // The output is 1 2 3 4 5 6 7 8.}