详解快排的四种方式

快速排序是Hoare于1962年提出的⼀种⼆叉树结构的交换排序⽅法,其基本思想为:任取待排序元素 序列中的某元素作为基准值,按照该排序码将待排序集合分割成两⼦序列,左⼦序列中所有元素均⼩ 于基准值,右⼦序列中所有元素均⼤于基准值,然后最左右⼦序列重复该过程,直到所有元素都排列 在相应位置上为⽌。

1、lomuto前后指针法

复制代码
void Swap(int* x, int* y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}

int _QuickSort(int* arr, int left, int right)
{
	int key = left, slow = left, fast = left + 1;
	while (fast <= right)
	{
		if (arr[fast] < arr[key] && ++slow != fast)
		{
			Swap(&arr[fast], &arr[slow]);
		}
		fast++;
	}
	Swap(&arr[key], &arr[slow]);
	return slow;
}

void QuickSort(int* arr, int left, int right)
{
	if (left >= right)
	{
		return;
	}

	int key = _QuickSort(arr, left, right );
	//左子序列
	QuickSort(arr,left,key-1);
	//右子序列
	QuickSort(arr,key+1,right);
}

2、hoare版本

1)创建左右指针,确定基准值

2)从右向左找出⽐基准值⼩的数据,从左向右找出⽐基准值⼤的数据,左右指针数据交换,进⼊下次 循环

复制代码
int _QuickSort2(int* arr, int left, int right)
{
	int key = left;
	left++;
	while (left <= right)
	{
		//left找比key大的值
		while (left <= right && arr[left] < arr[key])
		{
			++left;
		}
		//left指向比key大的值

		//right找比key小的值
		while (left <= right && arr[right] > arr[key])
		{
			--right;
		}
		if (left <= right)
		{
			Swap(&arr[left++], &arr[right--]);
		}
	}
	Swap(&arr[key], &arr[right]);
	return right;
}

3、挖洞法

复制代码
int _QuickSort3(int* arr, int left, int right)
{
	int key = arr[left];
	int hole = left;
	while (left < right)
	{
		while (left < right && arr[right]>key)
		{
			right--;
		}
		arr[hole] = arr[right];
		hole = right;
		while (left < right && arr[left] < key)
		{
			left++;
		}
		arr[hole] = arr[left];
		hole = left;
	}
	arr[hole] = key;
	return hole;
}

4、非递归快排

复制代码
void QuickSortNoR(int* arr, int left, int right)
{
	ST st;
	STInit(&st);
	//[left,right],进栈时要right先进left后进这样出栈的顺序才是对的
	STpush(&st, right);
	STpush(&st, left);

	while (!StackEmpty(&st))
	{
		//[begin,end]
		int begin = STtop(&st);
		STpop(&st);

		int end = STtop(&st);
		STpop(&st);
		int key = begin;
		int slow = begin;
		int fast = begin + 1;
		while (fast<=end)
		{
			if (arr[fast] < arr[key] && ++slow != fast)
			{
				Swap(&arr[fast], &arr[slow]);
			}
			fast++;
		}
		Swap(&arr[slow], &arr[key]);
		key = slow;

		//左 [begin,key-1]
		//右 [key+1,end]

		if (key + 1 < end)
		{
			STpush(&st, end);
			STpush(&st, key + 1);
		}

		if (begin < key - 1)
		{
			STpush(&st, key-1);
			STpush(&st, begin);
		}

	}

}
相关推荐
补三补四8 分钟前
Shapley与SHAP
大数据·人工智能·算法·机器学习·数据分析
KarrySmile39 分钟前
Day17--二叉树--654. 最大二叉树,617. 合并二叉树,700. 二叉搜索树中的搜索,98. 验证二叉搜索树
数据结构·算法·二叉树·二叉搜索树·合并二叉树·最大二叉树·验证二叉搜索树
凤年徐41 分钟前
【数据结构与算法】21.合并两个有序链表(LeetCode)
c语言·数据结构·c++·笔记·算法·链表
程序员老冯头1 小时前
第三十二节 MATLAB函数
数据结构·算法·matlab
lifallen1 小时前
hadoop.yarn 带时间的LRU 延迟删除
java·大数据·数据结构·hadoop·分布式·算法
淮北4945 小时前
STL学习(十一、常用的算数算法和集合算法)
c++·vscode·学习·算法
糖葫芦君5 小时前
玻尔兹曼分布与玻尔兹曼探索
人工智能·算法·机器学习
摸鱼仙人~5 小时前
Redis 数据结构全景解析
数据结构·数据库·redis
花火|10 小时前
算法训练营day37 动态规划⑤ 完全背包 518. 零钱兑换 II、 377. 组合总和 Ⅳ、70. 爬楼梯 (进阶)
算法·动态规划
Neil今天也要学习10 小时前
永磁同步电机无速度算法--脉振方波注入法
算法