常用排序之快速排序

快速排序

基本思想

取待排序元素中的某一个元素作为基准值,按照该基准值将待排序集合分为两部分,左子序列中的元素均小于基准值,右子序列中的所有元素均大于基准值,然后左右子序列重复该过程,直到所有元素都已排好序。

快速排序整体上使用的是一个分治的思想,在实现方面需要将大问题化为一个个小问题,直到部分小区间全部有序或者小区间内没有数。在处理区间的问题上,我们使用的是前闭后闭的方式。
基于此我们可以写出如下代码

void __Quicksort(int *array, int left, int right)
{
	if(left == right){ //只有一个数已经有序
		return;
	}
	if(left > right){ //没有数不需要排序
		return;
	}

	int div = Partition(array, left, right);
	__Quicksort(array, left, div-1);
	__Quicksort(array, div+1, right);
}

void Quicksort(int *array, int size)
{
	__Quicksort(array, 0, size-1);
}

有三种方法来处理一个序列使小元素位于基准值的左边,大元素位于基准值的右边:

hoare法
挖坑法
前后指针法

hoare法
在这里插入图片描述

static void Swap(int *x, int *y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}

int Partition(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);
	}
	Swap(array+begin, array+right);
	return begin;
}

挖坑法
在这里插入图片描述

int Partition(int *array, int left, int right)
{
	int begin = left;
	int end = right;
	int key = array[right];
	while(begin < end){
		while(begin < end && array[begin] <= key){
			begin++;
		}
		array[end] = array[begin];
		while(begin < end && array[end] >= key){
			end--;
		}
		array[begin] = array[end];
	}
	array[begin] = key;
	return begin;
}

前后指针
定义两个变量div和cur都先指向第一个元素,使div始终指向比基准值小的最后一个元素,cur向后遍历,遇到比基准值小的便交换div和cur,直到cur走到基准值的前一个元素,交换array[div]和array[right]。

int Partition(int *array, int left, int right)
{
	int div = 0, cur = 0;
	for(div = left, cur = left; cur < right; cur++){
		if(array[cur] < array[right]){
			Swap(array+div, array+cur);
			div++;
		}
	}
	Swap(array+div, array+right);
	return div;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值