排序算法_C++11的实现

博主通过学习《STL源码剖析》和C++11,尝试自己动手实现排序算法,关注对象拥有move构造函数和move赋值函数的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值