快速排序

快速排序也是一种分治法的实现。与归并排序的不同是其操作是原地进行的,不需要额外的存储空间。

基本思路:

1、基数的选取,普通快速排序在序列<a1,a2,...,an>中指定a1或an为基数(本例为a1)。

2、记录基数为x。分别定义两个循环L:a2往后的循环;R:an往前的循。两个循环的终止条件是L和R循环到同一个元素时。起始有个空位a1,通过将R循环中比基数x小的数ak放到a1,此时得到空位k,再进行L循环,将比基数x大的数aj放到k的位置,得到空位j。如此反复,当最终L和R指向同一个空位i时。将x放如位置i。则有i之前的元素小于x,i之后的元素大于小。即x已经排好序了。

3、递归排序<a1,...,ai-1>和<ai+1,an>,最终可以得到拍好序的序列。


算法实现

void QuickAdjust(int a[], int left, int right)
{
	if (left >= right)		//left>right为错误的赋值,=为排序元素个数为1
		return;
	int x = a[left];
	int l = left,r = right;	//初始化左右循环的起始值
	while(l < r) {
		while (l < r && a[r] >= x)
			r--;
		if(l < r)
			a[l++] = a[r];

		while(l < r && a[l] < x)
			l++;
		if(l < r)
			a[r--] = a[l];			
	}
	a[l] = x;
	QuickAdjust(a, left, l - 1);
	QuickAdjust(a, l + 1, right);
}

void QuickSort(int a[], int length)
{

	 QuickAdjust(a, 0, length - 1);	//left和right对应数组的下标
}

 

时间复杂度分析

最坏情况,当每次选取的基数都为序列中的最大值时,对n位序列的排序递归调用n-1位的排序,有T(n) = T(n-1) + T(1) + O(n),其中T(1)可视为0,即T(n) = T(n-1) + O(n)。可知最坏时间复杂度为O(n^2)。

最优情况,每次选取的基数为序列中的中间值,对n位序列的排序递归调用n/2位的排序。有T(n) = T(n/2) + O(n)。可知最优时间复杂度为O(nlog(n))。

 

另一个版本的快排(基数随机化)

因为上述快速排序对每次递归选定了特定位置的基数,在一定程度上使得最坏情况的出现概率增大(对排好序的序列时间复杂度最坏),采用基数随机化使时间复杂度接近平均情况。

主要的变化是采用随机函数random在每次递归调用时选取一个随机序号k在1到n之间,令a1与ak交换,再进行快速排序。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值