template<typename It> voidinsertionSort(It first, It last) { for(auto i = first + 1; i < last; ++i) { linear_insert(first, i); } }
template<typename It> voidlinear_insert(It first, It last) { // copy the value for the last element auto value = *last; // if the value is smaller than all the elements // then we do not need to perform swap, just shift // the range right by one slot if(value < *first) { copy_backward(first, last, last + 1); *first = value; } else { linear_insert(last, value); } }
template<typename It, typename T> voidlinear_insert(It last, T value) { auto next = last; --next; // we do not need to worry about whether // next will move out of range // because in the function above, // the situation value < *first // is already treated with care. while(value < *next) { //shift the value of next right by one slot *last = *next; last = next; --next; }
// the slot where the value should be put in *last = value;
template<typename It> voidshellSort(It first, It last) { auto len = last - first; size_t step = 1; while(step < len / 3) { step = step * 3 + 1; } shellSort(first, last, step); }
template<typename It> voidshellSort(It first, It last, size_t step) { while(step) { for (auto i = first + step; i < last; ++i) { for (auto j = i; // this is a very smart way to avoid j move out of range j >= first + step && *j < *(j - step); j-= step) iter_swap(j, j - step); } step /= 3; }
template<typename It, typename Comp = less<typename iterator_traits<It>::value_type> > voidadjust_heap(It first, typename iterator_traits<It>::difference_type hole_idx, It last, const Comp& comp = less<typename iterator_traits<It>::value_type>{}) { // get the value of the hole auto hole = first + hole_idx; auto val = *hole; // get the secondChild It auto secondChild = hole + (hole - first) + 2;
while(secondChild < last) { // compare second child with first child if(comp(*secondChild, *(secondChild - 1))) --secondChild; // check if val is greater than both children if(comp(*secondChild, val)) break; *hole = *secondChild; hole = secondChild; secondChild = hole + (hole - first) + 2; }
// if it escape the loop because it does not // have a secondChild, we have to check if it // still needs to sink if(secondChild == last && comp(val, *(--secondChild))) { *hole = *secondChild; hole =secondChild; }
*hole = val; }
在堆排序之前需要先进行建堆,即从最后一个叶子节点开始,从后往前对堆中元素进行下沉操作
1 2 3 4 5 6 7 8 9
template<typename It, typename Comp = less<typename iterator_traits<It>::value_type> > voidmake_heap(It first, It last, const Comp& comp = less<typename iterator_traits<It>::value_type>{}) { for(auto hole_idx = (last - first - 2) / 2 + 1; hole_idx--;) { adjust_heap(first, hole_idx, last, comp); } }
template<typename It1, typename It2, typename It3> It3 merge_(It1 first1, It1 last1, It2 first2, It2 last2, It3 result) { while(first1 < last1 && first2 < last2) { if(*first2 < *first1) { *result = *first2; ++first2; } // be very careful about the order of comparing first2 and first1 // we must make sure when first1 and first2 are equivalent, // first1 will be added into the result first. else { *result = *first1; ++first1; }
#include<ext/memory> template<typename It> voidmergesort(It first, It last) { auto n = (last - first); // base case if(n == 0 || n == 1) return; // merge sort routine auto mid = first + n / 2; mergesort(first, mid); mergesort(mid, last); // apply for a buffer auto buf = __gnu_cxx::temporary_buffer<It, typename iterator_traits<It>::value_type>(first, last); auto buf_end = copy(first, mid, buf.begin()); merge(buf.begin(), buf_end, mid, last, first); }
classSolution { public: voidmerge(vector<int>& nums1, int m, vector<int>& nums2, int n) { // how many slots are not in used in nums1? auto freeSlotNum = nums1.size() - m; // initialize all three ptrs auto it1 = nums1.rbegin() + freeSlotNum; auto it2 = nums2.rbegin(); auto it = nums1.rbegin(); // merge from the end to begin. std::merge(it1, nums1.rend(), it2, nums2.rend(), it, greater<int>{}); } };
甚至可以写成一行
一行code
1 2 3 4 5 6 7
classSolution { public: voidmerge(vector<int>& nums1, int m, vector<int>& nums2, int n) { std::merge(nums1.rbegin() + nums1.size() - m, nums1.rend(), nums2.rbegin(), nums2.rend(), nums1.rbegin(), greater<int>{}); } };