快速排序的递归实现

        快速排序通常是排序的最佳选择,因为其平均的运行时间为O(nlgn )。最坏情况下每次划分都产生两个分别包含n-1个元素和一个元素的区域,此时时间复杂度为o(n²)。最佳情况下每次划分都将数组分成两个长度差不多的区域,此时时间复杂度与平均性能差不多。

       快速排序的递归形式如下:

void do_quick_sort( int array[], int low, int high )
{
	if( low < high )
	{
		int par = partition( array, low, high );
		do_quick_sort( array, low, par-1 );
		do_quick_sort( array, par+1, high );
	}
}

快速排序采用分治思想,其中partition函数实现的就是“分”,它将array[low,high]分成两部分,其中前一部分中的元素均小于后一部分中的元素。然后递归调用快速排序对分出来的两部分进行快速排序。

partition函数的代码如下:

int partition( int array[], int low, int high )
{
	int current = array[low];
	while( low < high )
	{
		while( low < high && array[high] >= current )//从后向前寻找第一个小于current的元素
			--high;//每次循环时都要确保low<high,否则会出现low>high的情形
		array[low] = array[high];
		while( low < high && array[low] <= current )//从前向后寻找第一个大于current的元素
			++low;
		array[high] = array[low];
	}
	array[low] = current;
	return low;
}

该函数可以分为4步理解:

1.从后向前寻找第一个小于current的元素,找到后将它赋值给array[low](array[low]已经由current保存,这也是划分的基准值),

2.然后从前向后寻找第一个大于current的元素,找到后将它赋值给array[high],

3.重复1、2,直至low==high,

4.将current赋值给array[low](或array[high]),这时current前面的值都小于等于它,后面的值都大于等于它,这样array就被分成的两部分

有几个问题需要注意:

1.不论从前向后查找或是从后向前查找都要判断low<high,否则,在循环过程中会出现high<low的情形

2.由于是递归算法,所以程序中必须要有递归结束的条件,即:low>high,所以如果low<high,则继续执行,否则,退出。

快速排序还有几个优化版本,随机化快排就是其中之一,这样是期望对数组的划分更加对称,避免最坏情况的发生。在随机化版本中,只需对partition函数进行修改就可以了。

int randomized_partition( int array[], int low, int high )
{
	if( low < high )
	{
		srand( (unsigned)time(0) );//为rand函数指定随机数种子
		int index = rand()%(high-low)+low;//产生[low,high)区间的随机数
		int temp = array[index];
		array[index] = array[low];
		array[low] = temp;
	}
	return partition( array, low, high );
}


通过随机指定[low,high]中的元素作为主元,可以获得较好的平均情况性能。很多人认为,快排的随机化版本是对足够大的输入的理想选择。

       

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值