常见的排序——交换排序(快速排序递归版)

本文介绍了交换排序中的快速排序方法,包括三种寻找基准值的策略:Hoare版本、挖坑法和前后指针版本。快速排序具有时间复杂度O(n*logn)和空间复杂度O(logn)的特点,尽管不稳定性,但综合性能优秀。

交换排序交换排序分为快速排序和冒泡排序,就是根据序列中两个值的比较结果来对换这两个数在序列中的位置,特点就是较大值向尾部移动,较小值向前部移动。
快速排序基本思路为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两个子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值。然后采用分治的思想,把一个问题变成两个同样小问题(用递归去解决)。

//进行找基准值,代码如下面的框栏所示。
//进行递归操作
void _QuickSort(int array[], int left, int right)
{
	//分出来的小区间里面有一个值或没有值说明区间内没有数了,递归也就结束了
	if (left >= right){
		return;
	}
	//定义一个基准值
	int div = Parition(array, left, right);
	//进行递归去排序
	_QuickSort(array, left, div - 1);
	_QuickSort(array, div + 1, right);
}
void QuickSort(int array[], int size)
{
	_QuickSort(array, 0, size - 1);
}

找基准值法1:hoare版本:基本思路:先将右边的值作为基准值,用两个指针,第一个开始指向头,第二个指向尾,第一个往右走,第二个往左边走,当第一个遇见比基准值大的停下来,第二个遇见比基准值小的停下来,然后交换两个数。直到两个指针同时指向同一个数,则将其与基准值交换,然后返回这两个指针其中一个即可。

void Swap(int *a, int *b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}
int Parition_1(int array[], int left, int right)
{
	int begin = left;
	int end = right;
	while (begin < end){
		//开始将最右边的值定为基准值
		while (begin < end&&array[begin] <=array[right]){
			begin++;
		}
		while (begin < end&&array[end] >= array[right]){
			end--;
		}
		//交换两个数值
		Swap(&array[begin], &array[end]);
	}
	//这是begin和end已经走到同一个元素上面,所有将其和基准值进行交换
	Swap(&array[begin], &array[right]);
	return begin;
}

找基准值法2:挖坑法:基本思路:将最右边的值作为基准值,然后将其取下来。然后,用两个指针,第一指针从右往左走,遇见比它大的停下来,将这个值去覆盖基准值。第二个指针从左边往右边走,遇见比它小的停下来,用这个值去覆盖刚才那个值。最后,循环结束此时第一个指针和第二个指针指向同一个元素,将其与基准值交换,然后返回这两个指针其中一个即可。

int Parition_2(int array[], int left, int right)
{
	int begin = left;
	int end = right;
	int pivot = array[end];
	while (begin < end){
		while (begin < end&&array[begin] <= array[right]){
			begin++;
		}
		array[end] = array[begin];//去覆盖
		while (begin < end&&array[end] >= array[right]){
			end--;
		}
		array[begin] = array[end];//去覆盖
	}
	//走到这里说明begin和end指向同一个值了
	array[begin] = pivot;
	return begin;
}

找基准值法3:前后指针版本:基本思想:用两个指针开始都指向left,然后循环其中一个指针,当它遇见比自己小的就和第二个指针进行交换,第二个指针在这个循环内部进行自加操作。最后循环完毕,交换第二个指针与right的值,然后返回第二个指针。

int Parition_3(int array[], int left, int right)
{
	//这里i遇见比他小的停下来,d遇见比他大的停下来
	int d = left;
	for (int i = 0; i < right; i++){
		if (array[i] < array[right]){
			Swap(&array[i], &array[d]);
			d++;
		}
	}
	Swap(&array[d], &array[right]);
	return d;
}

快速排序的特点总结:时间复杂度O(n*logn),空间复杂度O(logn),并且其不稳定。但快排的整体的综合性能和使用场景都比好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值