快速排序(详解)

#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
void swap(int &small, int& big)
{
	int temp;
	temp = small;
	small = big;
	big = temp;
}

void qSort(int arr[], int left, int right )
{
	int i, j, base;
	if (left < right )
	{
		i = left;
		j = right+1;//这里加1是因为do{j--}while(arr[j] > base )执行的是j--
		base = arr[left];
			do
			{
				/*
				|把变量base赋值为arr[left]即arr[0],以base为参照物
				|这里选择升序排序,即小数值在前面(即左边),大数值放后面(即右边),这里很关键!!!
				|游标i从左向右迭代,当arr[i]小于base时继续前进,即i++,如上述所说这里是升序排列
				|当游标i移动到arr[i]>base时,停止循环。
				*/
				do
				{
					i++;
				}while (arr[i] < base);
				/*
				|同样选择base作为参照物,游标j从右向左移动,如前面所述这里是升序排列
				|所以当j移动到arr[j]>base时,继续移动(这里是向左移动),即保持大数值在右边
				|当j移动到arr[j]<base时停止循环
				*/
				do{
					j--;
				}while(arr[j] > base);

				/*
				|(附注)这里要判断(i<j)是因为在重复多次递归排序后,i左边的值要小于j右边的值。
				|此时若交换则会造成数值排序混乱
				|反观此处的目的,arr[i]是大于base的值,arr[j]是小于base的值
				|(因为在每一个时刻都用base左参照物)
				|所以交换arr[i]和arr[j],让小数值放在左边,大数值放在右边。
				|也正如上面所说这里是升序排列
				*/
				if (i < j)
					swap(arr[j], arr[i] );
			}while(i<j);
			/*
			|swap(arr[j], arr[left])这个函数可能比较难以理解
			|大家可以想象一下,上面的最外层do{...}while(i<j)为何终止并退出循环?
			|因为刚开始循环时i从左至右,j从右向左,所以随着循环的进行
			|当满足arr[i]>base,arr[j]<base时,j有可能出现在i的左边,所以会退出循环
			|
			|
			|但关键是这里为何交换arr[j]和参照物base==arr[left]呢?
			|因为		do{
			|				j--;
			|			  }while(arr[j] > base);
			|循环终止的原因是arr[j]<base(即arr[left]).
			|所以这里要交换arr[j]和arr[left]
			|交换的理由还是因为升序排列,小数值在左,大数值在右。
			|
			|
			|反观如果不交换arr[j]和arr[left](即base)的值会如何?
			|
			|如果不交换那么这个base在每次递归调用中永远处于最左边,也就没有加入排序。
			*/
			swap(arr[j], arr[left]);
			/*
			|	if (arr[j] != arr[left])
			|		swap(arr[j], arr[left]);
			|附注:上面执行do{j--}while(arr[j] > base )
			|j在向左移动时,可能在arr[j]=base时,这时候do{..}while循环也是会终止的
			|所以在他们不相等,才交换,反过来说就是不对单原子本身执行交换
			*/
			//递归调用
			qSort(arr, left, j-1);
			qSort(arr, j+1, right);
	}//if(left < right)

}

#define SIZE 1000

//进行过百万级别测试。
void main()
{
	int iArray[SIZE];
	//time()传入NULL值时返回当前系统时间。
	srand(unsigned int(time(NULL)));
	for (int i = 0; i <= SIZE; i++)
		iArray[i] = int(rand()%500+1);
	
	qSort(iArray, 0, SIZE);

	for (int j = 0; j <= SIZE; j++)
		cout << iArray[j]<<" ";

		cin.get();

		return;
}
/*
附注:快速排序函数内最后还是换上这句:
if (arr[j] != arr[left])
	swap(arr[j], arr[left]);
当arr[j]和arr[left]相等时不进行交换,在极限测试里相等还交换会带来极大开销
比如:调用swap()函数时,会产生函数调用时间 和 临时堆栈空间 以及释放临时堆栈的时间。
而相比cpu的速度计算两个数是否相等时是很快的。
*/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值