算法 快速排序QuickSort

先找一个标准值,将小于标准值的放在左侧,大于标准值的放在右侧,两边再重复此操作

快排是分治的经典应用

1.找个标准值(枢轴)

2.将标准值保存

3.从右向左找比标准值小的放入左侧坑

   从左向右找比标准值大的放入右侧坑

   重复此过程直到相遇

4.放入标准值到相遇的位置

5.对左右两部分做相同的处理

int Sort(int* arr, int begin, int end) {
	int temp = arr[begin];//保存标准值
	//遍历
	while (begin<end)
	{
		//从右向左找比标准值小的位置
		while (end > begin) {
			if (arr[end] < temp) {
				//填入左侧坑,此时是begin在标记
				arr[begin] = arr[end];
				begin++;
				break;
			}
			end--;
		}
		//从左向右找比标准值大的位置
		while ( begin < end) {
			if (arr[begin] > temp) {
				//填入右侧坑,此时是end在标记
				arr[end] = arr[begin];
				end--;
				break;
			}
			begin++;
		}
	}
	//填入标准值
	arr[begin] = temp;
	return begin;//返回标准值位置
}
void QuickSort(int* arr, int begin, int end) {

	if (arr == NULL || begin >= end)return;

	//标准值位置
	int nStandard;
	nStandard = Sort(arr, begin, end);
	//分割
	QuickSort(arr, begin, nStandard - 1);
	QuickSort(arr, nStandard +1, end);

}

区间分割法

1.定义一个small边界,初值为begin-1 定义一个标准值为数组最后一个元素arr[end]

2.遍历数组,如果数组元素比标准值小: 小区间扩张,arr[small+1]与arr[i]当前值进行交换

3.遍历结束后把标准值放在small+1的位置上

int Sort2(int* arr, int begin, int end) {
	int small = begin - 1;//小区间边界从begin-1开始
	for (begin; begin < end; begin++) {
        //遍历数组如果比标准值小,让那个i位置的值与小区间边界+1位置的值交换,边界偏移
		if (arr[begin] < arr[end]) {//标准值为最后一个数arr[end]
			if (++small != begin) {//异或交换时如果对同一个变量交换会把这个变量变为0
				arr[small] ^= arr[begin];
				arr[begin] ^= arr[small];
				arr[small] ^= arr[begin];
			}
		}
	}
    //最后将标准值也放入
	if (++small != end) {//异或交换时如果对同一个变量交换会把这个变量变为0
		arr[small] ^= arr[end];
		arr[end] ^= arr[small];
		arr[small] ^= arr[end];
	}
	return small;
}
void QuickSort(int* arr, int begin, int end) {

	if (arr == NULL || begin >= end)return;
	//标准值位置
	int nStandard;
	nStandard = Sort2(arr, begin, end);
	//分割,同样方法处理标准值的左边和右边
	QuickSort(arr, begin, nStandard - 1);
	QuickSort(arr, nStandard +1, end);

}

快排的其他优化方法

标准值选择 3选1 9选1

标准值聚集,可以把与标准值相同的放到最左或最右,最后再与标准值的左或右边交换

当元素数量小于16的时候改用插入排序

循环+堆空间 代替 递归 (减少崩溃可能性)

尾递归

  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值