快速排序算法

今天了解了一下快速排序算法,写个博客巩固一下。快速排序有很多种,今天只讲一种。
快速排序采用了分治法来实现排序,但是我觉得菜鸟教程里面的“挖坑+分治”更加全面。如果我们要对下面的数组num进行排序。

0123456789
57784566127623893256

设置基准数

我们取第一个数为基准数,int x=num[0]=57;再设置两个变量待会来操作数组元素
int i=0,j=9;接下来我们要做的是
1.将数组中比基准数小的元素放在基准数前面
2.将数组中比基准数大的元素放在基准数后面
3.将基准数左右两边的区间重复进行第一步和第二步,直到左右两区间只有一个数。
这里用挖坑来比喻讲解起来会比较好理解一点。首先在int x=num[0];取出基准值这一步中我们就开始挖坑了,就是在数组的第一个元素这里挖了个坑。那么接下来我们就要填坑了,我们要从数组的后面往前面找,找到一个比基准值小的元素,把他挖出来,填到我们刚才挖的坑中。刚刚的坑被填上后我们就不需要再填它了,所以要向后移一位,比如在这里我们就把num[9]的56挖出来填到num[0]里面,这一步是保证基准数右边的元素比基准数小。下面是代码

while (i<j&&num[j] >= x)//从后往前找
			j--;
		if (i < j) {
			num[i] = num[j];//填坑
			i++;//向后移一位
		}

但是这样我们又产生了新的坑,所以接下来我们要从前往后找,用数组里比基准数大的元素填上新坑。同样的,刚刚的坑被填上后我们就不需要再填它了,所以要向前移一位,这一步是保证基准数右边的元素比基准数大。

while (i < j&&num[i]<x)//从前往后找
			i++;
		if (i < j) {
			num[j] = num[i];//填坑
			j--;//向前移一位
		}

这样变量i和j就一直往前和往后移动,一直移动到i和j相等时停止移动,i和j停止移动的位置,就是基准数的最终位置,所以完整代码如下:

int AdjustArray(int *num, int l, int r) {
	int i = l;
	int j = r;
	int x = num[l];
	while (i<j)
	{
		while (i<j&&num[j] >= x)//从后往前找,没有找到比x小的就继续移位
			j--;
		if (i < j) {
			num[i] = num[j];//填坑
			i++;//向后移一位
		}
		while (i < j&&num[i]<x)//从前往后找,没有找到比x大的就继续移位
			i++;
		if (i < j) {
			num[j] = num[i];//填坑
			j--;//向前移一位
		}
	}
	num[i] = x;//当i和j相等时跳出循环,其位置为基准数位置
	return i;
}
void quicksort(int *num, int l, int r) {
	if (l<r) {
		int i = AdjustArray(num, l, r);
		quicksort(num, i + 1, r);//递归来对基准数的右边区间进行排序
		quicksort(num, l, i - 1);//递归来对基准数的左边区间进行排序
	}
}

AdjustArray函数是返回基准数的位置,我们这时只进行了一次排序,这还没完,因为这时数组是这样的

0123456789
56324523125776896678

我们看到只是保证了基准数57的左边都比57小,右边都比57大。所以还要对基准数的左边和右边区间重复上述排序过程,直到各区间只有一个数,这里用递归实现。
这个快速排序方法我也是看菜鸟教程学会的,我只是用自己的话总结了一下。快速排序还有很多种,等我后面慢慢学习后再写成博客分享给大家。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值