详解快速排序

详解快速排序

快速排序:又称为划分交换排序。是双冒泡,即对冒泡排序的改进。优点是在单线程进程里排序速度比较快,缺点是当排序文件记录已经有序或者基本有序时,该排序会逐渐退化为冒泡排序,使得时间复杂度为O(n^2)(有关时间复杂度可以参照之前的文章),另一个缺点是不稳定。
基本思想:在无序区间arr[left,right]中任取一个记录作为排序基准,可以假设为区间最左端的left,保存为临时值,然后用此基准划分区间arr1[left,i-1]和arr2[i+1,right],使得arr1的所有的值小于等于基准值,arr2的所有的值大于等于基准值,称为一趟排序。继续对两个区间进行划分,使得区间为空则停止划分。
演示代码

  1. 方法一(以左边为基准)
void show(int *arr, int n) {
	printf("\n状态");
	for (int i = 0; i < n; i++) {
		printf("%3d", arr[i]);
	}
}
//做一次划分
int partition(int *arr, int i, int j) {
	int tmp = arr[i];
	while (i < j) {
		while (arr[j] >= tmp&&i < j)j--;
		if (i < j) {
			arr[i] = arr[j];
			i++;
		}
		while (arr[i] <= tmp&&i < j)i++;
		if (i < j) {
			arr[j] = arr[i];
			j--;
		}
	}
	arr[i] = tmp;
	return i;
}
void quickSort3(int *arr, int left, int right) {
	int p = 0;
	if (left < right) {
		p = partition(arr, left, right);
		quickSort3(arr, left, p - 1);
		quickSort3(arr, p + 1, right);
	}
}
void main() {
	int arr[10] = { 10,9,20,19,13,8,9,22,0,91 };
	quickSort3(arr, 0, 9);
	show(arr, 10);
	system("pause");
}

测试结果:
在这里插入图片描述

  1. 方法二(以右边为基准)
void swap(int *i, int *j) {
	int tmp = *i;
	*i = *j;
	*j = tmp;
}
void quickSort2(int *arr, int iLeft, int iRight) {
	int i = iLeft - 1;
	int j = iRight;
	while (i < j) {
		do {
			do {
				j--;
			} while (arr[j] > arr[iRight] && j >= iLeft);
			do {
				i++;
			} while (arr[i] < arr[iRight] && i < iRight);
			if (i < j)swap(&arr[i], &arr[j]);
		} while (i < j);
		swap(&arr[i], &arr[iRight]);
		quickSort2(arr, iLeft, i - 1);
		quickSort2(arr, i + 1, iRight);
	}
}
void main() {
	int arr[10] = { 10,9,20,19,13,8,9,22,0,91 };
	quickSort2(arr, 0, 9);
	show(arr, 10);
	system("pause");
}

测试结果同上。
大家认为哪种方法好呢?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值