#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的速度计算两个数是否相等时是很快的。
*/
08-05
08-05
08-05
08-05
08-05