首先,根据啊哈算法里的代码,当两个下标相遇的时候(设此时数组下标位置为K),最左边的基准数会与位置为K的数交换位置。其次,当最右边的哨兵j停下时,标志着j当前位置对应的数字小于基准数。当最左边的哨兵i停下时,标志着i当前位置对应的数字大于基准数。
也就是说,在两个哨兵相遇的那一次循环里,如果先让i停下(此时这个位置就是K了),那这个位置上的数字就是大于基准数的。然后,位置K上的数字与基准数交换的话,就不是从小到大排序了。
逻辑思维,关注点在相遇的时候,从左侧先走相遇的时候可以保证左边的都是小于标准值的,但是相遇时候的值是要大于标准值(或者已经走到最右边都没有大于标准值的),从右侧走正好是右边都是大于标准值的,但是相遇的时候值是小于标准值(或者走到 最左边都没有小于标准值)。所以要从基数的对面开始。两种情况,就看你从哪开始扫描。不一定非要从右边开始哦!也可以从左边的,那标准值就选右边的。
#include <stdio.h>
int a[101],n;//定义全局变量,这两个变量需要在子函数中使用
void quicksort(int left, int right) {
int i, j, t, temp;
if(left > right)
return;
temp = a[left]; //temp中存的就是基准数
i = left;
j = right;
while(i != j) { //顺序很重要,要先从右边开始找
while(a[j] >= temp && i < j)
j--;
while(a[i] <= temp && i < j)//再找左边的
i++;
if(i < j)//交换两个数在数组中的位置
{
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
//最终将基准数归位
a[left] = a[i];
a[i] = temp;
quicksort(left, i-1);//继续处理左边的,这里是一个递归的过程
quicksort(i+1, right);//继续处理右边的 ,这里是一个递归的过程
}
int main() {
int i;
//读入数据
scanf("%d", &n);
for(i = 1; i <= n; i++)
scanf("%d", &a[i]);
quicksort(1, n); //快速排序调用
//输出排序后的结果
for(i = 1; i < n; i++)
printf("%d ", a[i]);
printf("%d\n", a[n]);
return 0;
}
快速排序的注意点:
a[j]>=tmp a[j]<=tmp中,这个等号一定不要忘记写。
新的写法:
P277