快速排序原理
简单的说,就是选取一个关键词(key) 将一个数列划分为两侧,一侧全部大于key,另一侧全部小于key.然后在分别对每一侧重复进行上述过程。直到最终排完序。
示意图来自百度百科“快速排序算法”词条,本图选取的是最左端的数位为key.
算法
注意:下面的是选取最右边的数为key(下面写为k), 与上面示意图不同。
a1,a2,⋯,an
数组位数 0 1 n-1
位置 left right
i,j初始位置 i j k
第一步:进行第一次切分:
当 j < right 时:
若array[i] > k, j++;
否则, array[i],array[j]的值互换。然后i++,j++
这步中的I是用于分隔大于k的数和小于k的数,而j则用于检索,检索出每一个数,再与k进行比较,若小于k,则与i所指的数互换,i++,移到下一位,这样j所检索出的小于k的数便被放到i的左边。j++,检索下一位。如果j检索到的值>k,则这个数本来就在i的右边了,不需要交换,j++,检索下一位。直到j= right ,完成检索,跳出循环。
第二步:交换i 和 j 所指的数,即将 k放到他应该在的位置,即这个位置的一边都是大于k的,一边都是小于k的。
第三步:如果left < i-1 (即此时的k - 1),即left 没有和i -1 重合,此时left 和 i - 1 间还有未排序元素,对其进行快速排序。
若 left == i - 1, 则左边排序完毕。
若i + 1 (此时的k+1) < right ,同理。
若切分后还未完成则继续切分进行快速排序,直到全部切分完毕,排序完毕,则完成。
虽然k的位置不同,但原理是相同的,可以参考开头的图来理解。
代码
#include<stdio.h>
void sort (int* array, int left, int right);
void swap (int *swap1, int *swap2);
int main() {
int counter = 0, len = 0;
int array[200] = {0}; //初始化
scanf("%d", &len); // 待排序数组长度
for (counter = 0; counter < len; counter++) {
scanf("%d", &array[counter]);
} //读入待排序数组
for (counter = 0; counter < len; counter++) {
printf("%d ", array[counter]);
} // 输出待排序数组,用于和排序后的比较。
sort (array, 0, len - 1);//排序
printf("\n");//输出换行符
for (counter = 0; counter < len; counter++) {
printf("%d ", array[counter]);
}//输出排序后数组
return 0;//结束程序
}
void sort (int* array, int left, int right) {
int i = left, j = left;//初始化,将i,j都置于待排序部分的最左端
for (; j < right ;) {
if (array[j] > array[right]) {//这里的array[right]就是上面讲的key
j++;
} else {
swap(&array[i++], &array[j++]);
}
}//第一步
swap(&array[i], &array[j]);//第二步
if (left < i - 1) sort(array, left, i-1);
if (right > i + 1) sort(array, i + 1, right);//第三步
}
void swap (int *swap1, int *swap2) {
int temp = *swap1;
*swap1 = *swap2;
*swap2 = temp;
}//用于交换的函数