泛型算法系列33:merge()&&inplace_merge()

#include #include #include #include #include #include using namespace std; /************************************************************************/ /* */ template inline _OutIt my_Merge(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest) { // copy merging ranges, both using operator< _DEBUG_ORDER(_First1, _Last1); _DEBUG_ORDER(_First2, _Last2); _DEBUG_POINTER(_Dest); for (; _First1 != _Last1 && _First2 != _Last2; ++_Dest) if (_DEBUG_LT(*_First2, *_First1))// if (_DEBUG_LT_PRED(_Pred, *_First2, *_First1)) *_Dest = *_First2, ++_First2; else *_Dest = *_First1, ++_First1; _Dest = _STDEXT unchecked_copy(_First1, _Last1, _Dest); // copy any tail return (_STDEXT unchecked_copy(_First2, _Last2, _Dest)); } /************************************************************************/ template void print_elements( Type elem ) { cout << elem << " "; } void (*pfi)( int ) = print_elements; int main() { int ia[] = {29,23,20,22,17,15,26,51,19,12,35,40}; int ia2[] = {74,16,39,54,21,44,62,10,27,41,65,71}; vector< int > vec1( ia, ia + 12 ); vector< int > vec2( ia2,ia2 + 12 ); int ia_result[24]; vector< int > vec_result(vec1.size()+vec2.size()); sort( ia, ia + 12 ); sort( ia2, ia2 + 12 ); // generates: // 10 12 15 16 17 19 20 21 22 23 26 27 29 35 // 39 40 41 44 51 54 62 65 71 74 my_Merge( ia, ia + 12, ia2, ia2 + 12, ia_result ); for_each( ia_result, ia_result + 24, pfi ); cout << "/n/n"; sort( vec1.begin(), vec1.end(), greater() ); sort( vec2.begin(), vec2.end(), greater() ); merge( vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), vec_result.begin(), greater() ); // generates: // 74 71 65 62 54 51 44 41 40 39 35 29 27 26 23 22 // 21 20 19 17 16 15 12 10 for_each( vec_result.begin(), vec_result.end(), pfi ); cout << "/n/n"; return 0; }

 

inplace_merge()

 

#include #include #include #include using namespace std; template void print_elements( Type elem ) { cout << elem << " "; } /************************************************************************/ /* */ template inline void my_Buffered_merge(_BidIt _First, _BidIt _Mid, _BidIt _Last, _Diff _Count1, _Diff _Count2, _Temp_iterator<_Ty>& _Tempbuf) { // merge [_First, _Mid) with [_Mid, _Last), using operator< if (_Count1 + _Count2 == 2) { // order two one-element partitions if (_DEBUG_LT(*_Mid, *_First)) std::iter_swap(_First, _Mid); } else if (_Count1 <= _Count2 && _Count1 <= _Tempbuf._Maxlen()) { // buffer left partition, then merge _STDEXT unchecked_copy(_First, _Mid, _Tempbuf._Init()); _STDEXT unchecked_merge(_Tempbuf._First(), _Tempbuf._Last(), _Mid, _Last, _First); } else if (_Count2 <= _Tempbuf._Maxlen()) { // buffer right partition, then merge _STDEXT unchecked_copy(_Mid, _Last, _Tempbuf._Init()); _STDEXT _Unchecked_merge_backward(_First, _Mid, _Tempbuf._First(), _Tempbuf._Last(), _Last); } else { // buffer too small, divide and conquer _BidIt _Firstn, _Lastn; _Diff _Count1n, _Count2n; if (_Count2 < _Count1) { // left larger, cut it in half and partition right to match _Count1n = _Count1 / 2, _Count2n = 0; _Firstn = _First; std::advance(_Firstn, _Count1n); _Lastn = std::lower_bound(_Mid, _Last, *_Firstn); _Distance(_Mid, _Lastn, _Count2n); } else { // right larger, cut it in half and partition left to match _Count1n = 0, _Count2n = _Count2 / 2; _Lastn = _Mid; std::advance(_Lastn, _Count2n); _Firstn = std::upper_bound(_First, _Mid, *_Lastn); _Distance(_First, _Firstn, _Count1n); } _BidIt _Midn = _Buffered_rotate(_Firstn, _Mid, _Lastn, _Count1 - _Count1n, _Count2n, _Tempbuf); // rearrange middle my_Buffered_merge(_First, _Firstn, _Midn, _Count1n, _Count2n, _Tempbuf); // merge each new part my_Buffered_merge(_Midn, _Lastn, _Last, _Count1 - _Count1n, _Count2 - _Count2n, _Tempbuf); } } template inline void my_Inplace_merge(_BidIt _First, _BidIt _Mid, _BidIt _Last) { // merge [_First, _Mid) with [_Mid, _Last), using operator< _DEBUG_ORDER(_First, _Mid); _DEBUG_ORDER(_Mid, _Last); iterator_traits<_BidIt>::difference_type _Count1 = 0; _Distance(_First, _Mid, _Count1); iterator_traits<_BidIt>::difference_type _Count2 = 0; _Distance(_Mid, _Last, _Count2); typedef typename iterator_traits<_BidIt>::value_type _Ty; _Temp_iterator<_Ty> _Tempbuf(_Count1 < _Count2 ? _Count1 : _Count2); my_Buffered_merge(_First, _Mid, _Last, _Count1, _Count2, _Tempbuf); } /************************************************************************/ /* * generates: ia sorted into two subarrays: 12 15 17 20 23 26 29 35 40 51 10 16 21 41 44 54 62 65 71 74 ia inplace_merge: 10 12 15 16 17 20 21 23 26 29 35 40 41 44 51 54 62 65 71 74 ivec sorted into two subvectors: 51 40 35 29 26 23 20 17 15 12 74 71 65 62 54 44 41 21 16 10 ivec inplace_merge: 74 71 65 62 54 51 44 41 40 35 29 26 23 21 20 17 16 15 12 10 */ int main() { int ia[] = { 29,23,20,17,15,26,51,12,35,40, 74,16,54,21,44,62,10,41,65,71 }; vector< int > ivec( ia, ia + 20 ); void (*pfi)( int ) = print_elements; // place the two subsequences in sorted order sort( &ia[0], &ia[10] ); sort( &ia[10], &ia[20] ); cout << "ia sorted into two sub-arrays: /n"; for_each( ia, ia + 20, pfi ); cout << "/n/n"; my_Inplace_merge( ia, ia + 10, ia + 20 ); cout << "ia inplace_merge:/n"; for_each( ia, ia + 20, pfi ); cout << "/n/n"; sort( ivec.begin(), ivec.begin() + 10, greater() ); sort( ivec.begin() + 10, ivec.end(), greater() ); cout << "ivec sorted into two sub-vectors: /n"; for_each( ivec.begin(), ivec.end(), pfi ); cout << "/n/n"; inplace_merge( ivec.begin(), ivec.begin() + 10, ivec.end(), greater() ); cout << "ivec inplace_merge:/n"; for_each( ivec.begin(), ivec.end(), pfi ); cout << endl; return 0; }

你可能感兴趣的:(C++,STL,merge,算法,iterator,distance,vector,each)