六大排序算法(4):快速排序

目录

思路介绍

步骤

代码

快速排序的优化代码

优化一

优化二

性能


思路介绍

快速排序是对冒泡排序算法的一种改进。以一个数为基准,将数组分为两个子序列,左子序列放比基准数小的数,右子序列放比基准数大的数,然后再将子序列以上述方式操作,直到整个数组有序。

步骤

采用挖坑法

1、定义变量key,存储数组第一个数作为key,左右两个指针指向数组的开头和结尾

2、从右指针开始移动,找到比key值小的,放入左指针的坑里,右指针形成新坑

3、切换到左指针移动,找比key大的值,放入到右指针的坑里,左指针形成新坑

4、依次循环直到左右指针相遇,将key放入到这个坑中

5、之后左右两个子序列递归调用此步骤,直到整个数组有序

代码

void QuickSort(int* arr, int size) {
	if (size < 2)return;
	int key = arr[0];
	int left = 0;
	int right = size - 1;
	int flag = 2; //标志位为1移动左指针,标志位为2移动右指针

	while (left < right) {
		if (flag == 2) { //先移动右指针
			if (arr[right] >= key) {right--; continue;}
			arr[left] = arr[right];
			left++;
			flag = 1;
			continue;
		}
		if (flag == 1) { //移动左指针
			if (arr[left] <= key) { left++; continue; }
			arr[right] = arr[left];
			right--;
			flag = 2;
			continue;
		}
	}

	arr[left] = key; //此时left==right

	//递归调用左右子序列
	QuickSort(arr, left); //左子序列
	QuickSort(arr + left + 1, size - left - 1);
}

快速排序的优化代码

优化一

采用更合理的基准数(key),减少递归深度,例如随机选、选中间位置、三值或多值取折中等。

优化二

快速排序时以递归形式对分好大小的两个子序列进行单趟排序,若是递归到较深处时,待排数组较短,但是数量也越多,调用函数的次数就越多,开辟函数栈帧的消耗越大,导致效率下降。因此可以设置一个数组排序的长度下限,若是数组长度到达下限以下,则不再调用快速排序,而是调用插入排序。

void QuickSort2(int* arr, int size) {
	if (size < 2)return;
	if (size <= 8) { //例如数组长度小于等于8时,调用插入排序
		//插入排序
		insertSort(arr, size);
		return;
	}
	int key = arr[0];
	int left = 0;
	int right = size - 1;
	int flag = 2; //标志位为1移动左指针,标志位为2移动右指针

	while (left < right) {
		if (flag == 2) { //先移动右指针
			if (arr[right] >= key) { right--; continue; }
			arr[left] = arr[right];
			left++;
			flag = 1;
			continue;
		}
		if (flag == 1) { //移动左指针
			if (arr[left] <= key) { left++; continue; }
			arr[right] = arr[left];
			right--;
			flag = 2;
			continue;
		}
	}

	arr[left] = key; //此时left==right

	//递归调用左右子序列
	QuickSort(arr, left); //左子序列
	QuickSort(arr + left + 1, size - left - 1);
}

性能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值