近来在学习<<STL源码剖析>>和C++11,按自己的理解自己动手实现排序算法的实现,代码中多用C++11的新特性。
这算是自娱自乐吧
这里只考虑排序的对象的有move构造函数,move赋值函数。
- #ifndef YYRSort_H_
- #define YYRSort_H_
- #include <algorithm>
- using namespace std;
- const size_t Threshold = 16;
- namespace YYRSort
- {
- //插入排序
- template<typename RandomIterator>
- inline void InsertionSort(RandomIterator first, RandomIterator last)
- {
- if((last-first) < 2) //It don't need to sort when the container only has one or zero element.
- {
- return;
- };
- auto Index = first + 1;
- decltype(Index) NextPos;
- decltype(Index) PrePos;
- auto TempValue = *Index;
- for(;Index != last; ++Index)
- {
- NextPos = Index - 1;
- PrePos = Index;
- TempValue = std::move(*Index);
- if(TempValue < *first)
- {
- std::move_backward(first, Index, Index+1);
- *first = std::move(TempValue);
- }
- else
- {
- while(true)
- {
- if(TempValue < *NextPos)
- {
- *PrePos = std::move(*NextPos);
- PrePos = NextPos;
- --NextPos;
- }
- else
- {
- *PrePos = std::move(TempValue);
- break;
- }
- }
- }
- }
- }
- //生成最大堆
- template<typename RandomIterator>
- inline void Make_Heap(RandomIterator first, RandomIterator last)
- {
- if((last-first) < 2)
- {
- return;
- }
- auto TempValue = *first;
- for(auto Pos = first + 1; Pos != last; ++Pos)
- {
- auto Index = ((Pos - first) - 1) / 2;
- auto Parent = Pos;
- decltype(Pos) Child;
- while(true)
- {
- Child = Parent;
- Parent = first + Index;
- if(*Parent < *Child)
- {
- TempValue = std::move(*Parent);
- *Parent = std::move(*Child);
- *Child = std::move(TempValue);
- if(Index == 0)
- {
- break;
- }
- Index = (Index - 1) / 2;
- }
- else
- {
- break;
- }
- }
- }
- }
- //堆排序
- template<typename RandomIterator>
- inline void Sort_Heap(RandomIterator first, RandomIterator last)
- {
- if((last-first) < 2)
- {
- return;
- }
- Make_Heap(first, last);
- --last;
- auto TempValue = *first;
- for(; first < last; --last)
- {
- TempValue = std::move(*first);
- *first = std::move(*last);
- *last = std::move(TempValue);
- size_t Index = 0;
- auto Parent = first;
- while(true)
- {
- Index = (Index * 2) + 1;
- auto LeftChild = first + Index;
- if(!(LeftChild < last))
- {
- break;
- }
- auto RightChild = LeftChild + 1;
- if(!(RightChild < last))
- {
- if(*Parent < *LeftChild)
- {
- TempValue = std::move(*Parent);
- *Parent = std::move(*LeftChild);
- *LeftChild = std::move(TempValue);
- Parent = LeftChild;
- }
- else
- {
- break;
- }
- }
- else
- {
- if(*Parent < *LeftChild)
- {
- if(*LeftChild < *RightChild)
- {
- TempValue = std::move(*Parent);
- *Parent = std::move(*RightChild);
- *RightChild = std::move(TempValue);
- Parent = RightChild;
- ++Index;
- }
- else
- {
- TempValue = std::move(*Parent);
- *Parent = std::move(*LeftChild);
- *LeftChild = std::move(TempValue);
- Parent = LeftChild;
- }
- }
- else
- {
- if(*Parent < *RightChild)
- {
- TempValue = std::move(*Parent);
- *Parent = std::move(*RightChild);
- *RightChild = std::move(TempValue);
- Parent = RightChild;
- ++Index;
- }
- else
- {
- break;
- }
- }
- }
- }
- }
- }
- //取三个值的中值
- template<typename T>
- inline T& MedianThree(T& A, T& B, T& C)
- {
- if(A < B)
- {
- if(C < A)
- {
- return A;
- }
- else if(B < C)
- {
- return B;
- }
- else
- {
- return C;
- }
- }
- else
- {
- if(C < B)
- {
- return B;
- }
- else if(A < C)
- {
- return A;
- }
- else
- {
- return C;
- }
- }
- }
- //分割区间为2个子区间,左边区间所有元素都小于右边区间的任意一个原始,返回左边区间的开始位置
- template<typename RandomIterator, typename T>
- inline RandomIterator Partition(RandomIterator first, RandomIterator last, T MidValue)
- {
- T TempValue = *first;
- while(true)
- {
- while(*first < MidValue)
- {
- ++first;
- }
- --last;
- while(MidValue < *last)
- {
- --last;
- }
- if(!(first < last))
- {
- return first;
- }
- TempValue = std::move(*first);
- *first = std::move(*last);
- *last = std::move(TempValue);
- ++first;
- }
- }
- //快速排序
- template<typename RandomIterator>
- void QuickSort(RandomIterator first, RandomIterator last)
- {
- if(last - first < 2)
- {
- return;
- };
- auto DivPos = Partition(first, last,
- MedianThree(*first, *(last-1), *(first + (last-first)/2)));
- QuickSort(first, DivPos);
- QuickSort(DivPos, last);
- }
- inline size_t _lg(size_t S)
- {
- size_t Ret = 0;
- while(S > 1)
- {
- ++Ret;
- S /= 2;
- }
- return Ret;
- }
- template<typename RandomIterator>
- void _IntroSort(RandomIterator first, RandomIterator last, size_t LayerLimit)
- {
- if(last - first > Threshold)
- {
- if(LayerLimit > 0)
- {
- auto DivPos = Partition(first, last, MedianThree(*first, *(last-1), *(first + (last-first)/2)));
- --LayerLimit;
- _IntroSort(first, DivPos, LayerLimit);
- _IntroSort(DivPos, last, LayerLimit);
- }
- else
- {
- Sort_Heap(first, last);
- }
- }
- }
- template<typename RandomIterator>
- inline void _InsertionSort_Unguard(RandomIterator first, RandomIterator last)
- {
- auto TempValue = *first;
- decltype(first) Pre;
- decltype(first) Next;
- for(auto Pos = first + 1; Pos != last; ++Pos)
- {
- Pre = Pos;
- Next = Pre - 1;
- TempValue = std::move(*Pos);
- while (true)
- {
- if(TempValue < *Next)
- {
- *Pre = std::move(*Next);
- Pre = Next;
- --Next;
- }
- else
- {
- *Pre = std::move(TempValue);
- break;
- }
- }
- }
- }
- template<typename RandomIterator>
- inline void _InsertionSort(RandomIterator first, RandomIterator last)
- {
- if((last - first) > Threshold)
- {
- InsertionSort(first, first + Threshold);
- _InsertionSort_Unguard(first, last);
- }
- else
- {
- InsertionSort(first, last);
- }
- }
- //混合排序
- template<typename RandomIterator>
- void Sort(RandomIterator first, RandomIterator last)
- {
- if((last - first) < 2)
- {
- return;
- }
- size_t LayerLimit = _lg(last - first) * 2;
- _IntroSort(first, last, LayerLimit);
- _InsertionSort(first, last);
- }
- }
- #endif
原文地址:http://blog.youkuaiyun.com/yyrrbadboy2012/article/details/8495072