原理
快速排序的本质是给基准数据寻找合适位置的过程。以升序为例,每一趟排序结束以后,可以保证基准数据左边的数据全部小于它,右边的数据全部大于它,这也表明这一基准数据已经处于它的最终位置了。
想要做到上述这一点,基本方法(称为霍尔(Hoare)法))如下:
1、将需要排序的区间中的第一个数据作为基准数据,记为key
2、从区间的最后一个数据向前寻找小于key的数据,记为end
3、从区间的第一个数据向后寻找大于key的数据,记为begin
4、交换begin和end所在位置的数据,重复2、3的操作
5、若begin和end相遇,则将区间第一个数据(即key)与相遇位置的数据交换,此时完成了一趟排序,key数据已经处于最终的位置。函数返回相遇位置。
之后通过递归调用的方式对相遇位置的左边和右边区间分别执行上述步骤,直到整个区间的每个数据都处于其最终位置,数组就有序了。
可参考下图例子:
根据以上思路编写的代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
void printArr(int* arr, int len){
for (int i = 0; i < len; i++){
printf("%d ", arr[i]);
}
printf("\n");
}
void Swap(int* a, int* b){
int tmp = *a;
*a = *b;
*b = tmp;
}
int partition(int* arr, int begin, int end){
int start = begin;
int key = arr[start];
while (begin < end){
while (begin < end && arr[end] >= key){
end--;
}
while (begin < end && arr[begin] <= key){
begin++;
}
Swap(&arr[begin], &arr[end]);
}
Swap(&arr[start], &arr[begin]);
return begin;
}
void quickSort(int* arr, int begin, int end){
if (begin >= end){
return;
}
int div = partition(arr, begin, end);
quickSort(arr, begin, div - 1);
quickSort(arr, div + 1, end);
}
void testQuickSort(){
int arr[] = { 10, 1, 3, 2, 0, 7, 5, 4, 6, 8, 9 };
int len = sizeof(arr) / sizeof(arr[0]);
printArr(arr, len);
quickSort(arr, 0, len - 1);
printArr(arr, len);
}
int main(){
testQuickSort();
system("pause");
return 0;
}
运行结果: