近来在学习<<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