几种排序算法的实现,写了就加

本文档介绍了C++中各种排序算法的模板实现,包括冒泡排序、鸡尾酒排序、直接选择排序、两路选择排序、快速挖掘排序、插入排序,适用于不同场景。使用了模板和自定义比较函数,适合通用和部分参数化的排序需求。

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

声明

#pragma once
#include<random>

class Sort
{
#define DefaultAscending  [](auto Left, auto Right) ->bool { return (Left > Right); }
#define DefaultDescending [](auto Left, auto Right) ->bool { return (Left < Right); }

#define QuickEqualAscending  [](auto Left, auto Right) ->bool { return (Left >= Right); }
#define QuickEqualDescending [](auto Left, auto Right) ->bool { return (Left <= Right); }

public:
	static constexpr size_t SmallArraySize = 10u;
	/*
	*	Simple parameters funcs
	*/

	template<typename T>
	static void Bubble(
		T* Array,
		const size_t& size,
		bool (*compare)(const T& Left, const T& Right) = DefaultAscending);

	template<typename T>
	static void Cocktail(
		T* Array,
		size_t size,
		bool (*compare)(const T& Left, const T& Right) = DefaultAscending);

	template<typename T>
	static void DirectSelection(
		T* Array,
		const size_t& size,
		bool (*compare)(const T& Left, const T& Right) = DefaultAscending);

	template<typename T>
	static void TwoWaySelection(
		T* Array,
		size_t size,
		bool (*compare)(const T& Left, const T& Right) = DefaultAscending);

	template<typename T>
	static void QuickDigging(
		T* Array,
		const size_t& size,
		bool (*compare)(const T& Left, const T& Right) = QuickEqualAscending);

	template<typename T>
	static void QuickDigging2(
		T* Array,
		const size_t& size,
		bool (*compare)(const T& Left, const T& Right) = QuickEqualAscending);

	template<typename T>
	static void Insertion(
		T* Array,
		const size_t& size,
		bool (*compare)(const T& Left, const T& Right) = DefaultAscending);

	/*
	*	Full parameters funcs
	*/

	template<typename T>
	static void Bubble(
		T *Array,
		const size_t &Start,
		const size_t &End,
		bool (*compare)(const T &Left,const T &Right) = DefaultAscending);

	template<typename T>
	static void Cocktail(
		T* Array,
		size_t Start,
		size_t End,
		bool (*compare)(const T& Left, const T& Right) = DefaultAscending);

	template<typename T>
	static void DirectSelection(
		T* Array,
		const size_t& Start,
		const size_t& End,
		bool (*compare)(const T& Left, const T& Right) = DefaultAscending);

	template<typename T>
	static void TwoWaySelection(
		T* Array,
		size_t Start,
		size_t End,
		bool (*compare)(const T& Left, const T& Right) = DefaultAscending);

	template<typename T>
	static void QuickDigging(
		T* Array,
		const size_t& Start,
		const size_t& End,
		bool (*compare)(const T& Left, const T& Right) = QuickEqualAscending);

	template<typename T>
	static void QuickDigging2(
		T* Array,
		const size_t& Start,
		const size_t& End,
		bool (*compare)(const T& Left, const T& Right) = QuickEqualAscending);

	template<typename T>
	static void Insertion(
		T* Array,
		const size_t& Start,
		const size_t& End,
		bool (*compare)(const T& Left, const T& Right) = DefaultAscending);
};

//-------------------------------------------------------------------------------------------------

定义

template<typename T>
inline void Sort::Bubble(T* Array, const size_t& size, bool(*compare)(const T& Left, const T& Right))
{
	Bubble(Array, 0u, size, compare);
}

template<typename T>
inline void Sort::Cocktail(T* Array, size_t size, bool(*compare)(const T& Left, const T& Right))
{
	Cocktail(Array, 0u, size, compare);
}

template<typename T>
inline void Sort::DirectSelection(T* Array, const size_t& size, bool(*compare)(const T& Left, const T& Right))
{
	DirectSelection(Array, 0u, size, compare);
}

template<typename T>
inline void Sort::TwoWaySelection(T* Array, size_t size, bool(*compare)(const T& Left, const T& Right))
{
	TwoWaySelection(Array, 0u, size, compare);
}

template<typename T>
inline void Sort::QuickDigging(T* Array, const size_t& size, bool(*compare)(const T& Left, const T& Right))
{
	QuickDigging(Array, 0u, size, compare);
}

template<typename T>
inline void Sort::QuickDigging2(T* Array, const size_t& size, bool(*compare)(const T& Left, const T& Right))
{
	QuickDigging2(Array, 0u, size, compare);
}

template<typename T>
inline void Sort::Insertion(T* Array, const size_t& size, bool(*compare)(const T& Left, const T& Right))
{
	Insertion(Array, 0u, size, compare);
}

//-------------------------------------------------------------------------------------------------
template<typename T>
inline void Sort::Bubble(
	T *Array,
	const size_t &Start,
	const size_t &End,
	bool (*compare)(const T &Left, const T &Right))
{
	bool IsOk;
	T tempValue;

	for (size_t i = Start; i < End; ++i)
	{
		IsOk = true;

		for (size_t j = Start; j < (End - 1u - i); ++j)
		{
			if (compare(Array[j], Array[j + 1u]))
			{
				// exchange
				tempValue = Array[j];
				Array[j] = Array[j + 1];
				Array[j + 1] = tempValue;

				IsOk = false;
			}
		}

		if (IsOk)break;// done
	}
}

template<typename T>
inline void Sort::Cocktail(
	T* Array,
	size_t Start,
	size_t End,
	bool(*compare)(const T& Left, const T& Right))
{
	bool IsOk;
	T tempValue;

	while (Start < (End - 1u))
	{
		// Forward
		IsOk = true;

		for (size_t i = Start; i < (End - 1u); ++i)
		{
			if (compare(Array[i], Array[i + 1u]))
			{
				// exchange
				tempValue = Array[i];
				Array[i] = Array[i + 1];
				Array[i + 1] = tempValue;

				IsOk = false;
			}
		}
		if (IsOk)break;// done
		--End;

		// Reverse
		IsOk = true;

		for (size_t i = (End - 1u); i > Start; --i)
		{
			if (compare(Array[i - 1], Array[i]))
			{
				// exchange
				tempValue = Array[i - 1];
				Array[i - 1] = Array[i];
				Array[i] = tempValue;

				IsOk = false;
			}
		}

		if (IsOk)break;// done
		++Start;
	}
}

template<typename T>
inline void Sort::DirectSelection(
	T* Array,
	const size_t& Start,
	const size_t& End,
	bool(*compare)(const T& Left, const T& Right))
{
	T tempValue;

	for (size_t i = Start, index; i < End; ++i)
	{
		index = i;

		for (size_t j = i + 1u; j < End; ++j)
		{
			if (compare(Array[index], Array[j]))
			{
				index = j;
			}
		}

		// exchange
		if (index > i)
		{
			tempValue = Array[i];
			Array[i] = Array[index];
			Array[index] = tempValue;
		}
	}
}

template<typename T>
inline void Sort::TwoWaySelection(
	T* Array,
	size_t Start,
	size_t End,
	bool(*compare)(const T& Left, const T& Right))
{
	T tempValue;
	size_t indexL,indexR;

	while (Start < (End - 1u))
	{
		indexL = indexR = Start;

		for (size_t i = Start + 1u; i < End; ++i)
		{
			if (compare(Array[indexL], Array[i]))
			{
				indexL = i;
			}
			if (compare(Array[i], Array[indexR]))
			{
				indexR = i;
			}
		}

		// exchange
		if (indexL > Start)
		{
			tempValue = Array[Start];
			Array[Start] = Array[indexL];
			Array[indexL] = tempValue;
		}
		++Start;

		//such as { indexR ... indexL}
		if ((indexR != (Start - 1u)) || (indexL != (End - 1u)))
		{
			//such as {indexR , indexL ...}
			if (indexR == (Start - 1u))
				++indexR;

			if (indexR < (End - 1u))
			{
				tempValue = Array[End - 1u];
				Array[End - 1u] = Array[indexR];
				Array[indexR] = tempValue;
			}
		}
		--End;
	}
}

template<typename T>
inline void Sort::QuickDigging(
	T* Array,
	const size_t& Start,
	const size_t& End,
	bool(*compare)(const T& Left, const T& Right))
{
	auto findPivot = [&Array,&compare](size_t left,size_t right)
	{
		static std::random_device Rand;

		size_t randId = (Rand() % (right - left) + left); // rand to limit the worst
		T pivot = Array[randId];
		Array[randId] = Array[left];

		--right;
		while (left < right)
		{
			while ((left < right) && compare(Array[right], pivot))	--right;
			Array[left] = Array[right];

			while ((left < right) && compare(pivot, Array[left]))	++left;
			Array[right] = Array[left];
		}

		Array[left] = pivot;
		return left;
	};

	if ((Start + 1u) < End)
	{
		size_t pivotId = findPivot(Start, End);

		QuickDigging(Array, Start, pivotId, compare);
		QuickDigging(Array, pivotId + 1u, End, compare);
	}
}

template<typename T>
inline void Sort::QuickDigging2(
	T* Array,
	const size_t& Start,
	const size_t& End,
	bool(*compare)(const T& Left, const T& Right))
{
	if ((End - Start) > SmallArraySize)
	{
		QuickDigging(Array, Start, End, compare);
	}
	else
	{
		// Insertion is better in small array
		Insertion(Array, Start, End, compare);
		return;
	}
}

template<typename T>
inline void Sort::Insertion(
	T* Array,
	const size_t& Start,
	const size_t& End,
	bool(*compare)(const T& Left, const T& Right))
{
	T tempValue;

	for (size_t i = Start, targetPos; i < (End - 1u); ++i)
	{
		for (targetPos = (i + 1u); targetPos > 0u; --targetPos)
		{
			if (!compare(Array[targetPos - 1u], Array[i + 1u]))
				break;
		}

		if (targetPos < (i + 1u))
		{
			tempValue = Array[i + 1u];

			std::copy(Array + targetPos, Array + (i + 1u), Array + (targetPos + 1u));
			Array[targetPos] = tempValue;
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值