快排作为一个常见的排序方式,校招的时候看过,没记到脑子中。最近在极度压抑的情况下,逼着自己,也算是学熟悉了。
关键点:
1,保留已经定位的位置 (之前一股脑的些,VS一直提醒说栈溢出,仔细想了下自己呆瓜自己好不容易跑一次比较,数值的位置已经定了,还不知耻的又拿去跑。不超出才怪)
2, 递归的终止条件 (这个一定要注意,要注意,要注意。if(left>=right) return; 看着只是一个不起眼的判断,实则很精妙 )
3, 两端遍历的数字之间交换的规律 (这个要注意,a[left]是temp, j是跑的最快的,即j是真正决定你跑的结果的。)
#include <stdio.h>
#include <stdlib.h>
// small --> big
void quicksort(int a[], int left,int right){
int i=left;
int j=right;
int temp=a[left];
if(left>=right)
return; //要设定终止条件
while (i!=j){
while (j>i && a[j]<=temp)
j--;
a[i]=a[j];
while (j>i && a[i]>=temp)
i++;
a[j]=a[i];
}
a[i]=temp;
quicksort(a,left,i-1);
quicksort(a,i+1,right);
}
void quickSort2(int a[],int left,int right)
{
int i=left;
int j=right;
int temp=a[left];
if(left>=right)
return;
while(i!=j)
{
while(i<j&&a[j]>=temp)
j--;
if(j>i)
a[i]=a[j];//a[i]已经赋值给temp,所以直接将a[j]赋值给a[i],赋值完之后a[j],有空位
while(i<j&&a[i]<=temp)
i++;
if(i<j)
a[j]=a[i];
}
a[i]=temp;//把基准插入,此时i与j已经相等R[low..pivotpos-1].keys≤R[pivotpos].key≤R[pivotpos+1..high].keys
quickSort2(a,left,i-1);/*递归左边*/
quickSort2(a,i+1,right);/*递归右边*/
}
int main1(void){
int a[10]={1,9,2,8,3,7,4,6,5,0};
// int length=sizeof(a)/sizeof(int);
int length=10;
quicksort(a,0,9);
//quickSort2(a,0,9);
for (int i=0;i<length;i++){
printf("%5d",a[i]);
}
system ("pause");
return 0;
}
快速排序有一个超级好的地方,o(n)复杂度求第K大的值。你的只要你的 i==K-1,那么a[k]的值就是第K大的值。 比起堆排序好太多了。