【数据结构】--快速排序

👉快速排序递归法

快速排序递归的基本思想:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该程,直到所有元素都排列在相应位置上为止

也就是说,分为若趟排序,每一趟排序都把一个元素排到它的指定位置。再以这个元素为分界,分成左右两个数列,再分别对左右两个数列循环重复使用该方法,每一次都确定一个元素的位置,直至数列全部有序

🍗hoare法

这个方法的基本思想:利用左右两个指针,假设每一趟需要确定位置的元素为key,key为最左边的元素,左指针指向最左边,右指针指向最右边。利用右指针找比key小的元素,找到后右指针先不动。再利用左指针找比key大的元素,找到后左右指针指向的元素交换。直至左右指针相遇,再把相遇点的元素和key交换,这样排完一趟后,key的左边都是比它小的元素,右边都是比它大的元素
在这里插入图片描述
这样单趟排完后,可以看到5(key)这个元素的左边都是比它小的,右边都是比它大的。
单趟排完后,以5作为分割,先排序5左边的数列,每次生成的
key
都作为分割,先把左边的数列排列有序,之后再排序key右边的数列直至整个数列全部有序即可。
利用递归法,当右指针等于或小于左指针的时候,该次递归结束

下图为全程演示
在这里插入图片描述

//hoare
int PartQuickSort1(int* a, int left, int right) {
   
	//单趟排序能够将一个数据排好,不需要再动了
	int key = left;
	while (left < right) {
   
		//右指针找小
		while (left < right && a[right] >= a[key])
			right--;

		//左指针找大
		while (left < right && a[left] <= a[key])
			left++;

		//左右都找到后交换两个数据
		//要注意避免左指针比右指针大了也交换
		if (left < right)
			Swap(&a[left], &a[right]);
	}
	
	//交换key和左右指针相遇点的数据
	int meet = left;
	Swap(&a[meet], &a[key]);

	//返回相遇点
	return meet;
}

void QuickSort(int* a, int begin, int end) {
   
	//递归结束的条件:当begin大于end时,或者等于end时
	if (begin >= end)
		return;

	int key = PartQuickSort1(a, begin, end);

	//单趟排序能够将一个数据排好,不需要再动了
	//所以递归实现每一次key位置的左边区间和右边区间
	QuickSort(a, begin, key - 1);
	QuickSort(a, key + 1, end);
}

🍗挖坑法

挖坑法和hoare法差不多,个人感觉挖坑法比hoare法的出错率更低
基本思想:先用key记录下最左边的值,然后最左边的位置形成一个坑位,右指针往前找比key要小的元素,找到之后填入坑位,右指针的位置变成一个新的坑位;接着左指针往后找比key大的元素,找到后填入右指针指向的坑位,左指针的位置变成一个新的坑位,依次往复循环,直到左指针和右指针相遇,相遇点就是一个坑位,再把key填入该坑位即可。

一趟排序过后,key的左边都是比它小的元素,右边都是比它大的元素

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值