# 快速排序法 快速排序是对冒泡法排序的一种改进。快速排序算法 的基本思想是:将所要进行排序的数分为左右两个部分,其中一部分的所有数据都比另外一 部分的数据小,然后将所分得的两部分数据进行同样的划分,重复执行以上的划分操作,直到所有要进行排序的数据变为有序为止。 可能仅根据基本思想对快速排序的认识并不深,接下来以对n个无序数列A[0], A[1]…, A[n-1]采用快速排序方法进行升序排列为例进行讲解。 (1)定义两个变量low和high,将low、high分别设置为要进行排序的序列的起始元素和最后一个元素的下标。第一次,low和high的取值分别为0和n-1,接下来的每次取值由划分得到的序列起始元素和最后一个元素的下标来决定。 (2)定义一个变量key,接下来以key的取值为基准将数组A划分为左右两个部分,通常,key值为要进行排序序列的第一个元素值。第一次的取值为A[0],以后毎次取值由要划分序列的起始元素决定。 (3)从high所指向的数组元素开始向左扫描,扫描的同时将下标为high的数组元素依次与划分基准值key进行比较操作,直到high不大于low或找到第一个小于基准值key的数组元素,然后将该值赋值给low所指向的数组元素,同时将low右移一个位置。 (4)如果low依然小于high,那么由low所指向的数组元素开始向右扫描,扫描的同时将下标为low的数组元素值依次与划分的基准值key进行比较操作,直到low不小于high或找到第一个大于基准值key的数组元素,然后将该值赋给high所指向的数组元素,同时将high左移一个位置。 (5)重复步骤(3) (4),直到low的植不小于high为止,这时成功划分后得到的左右两部分分别为A[low……pos-1]和A[pos+1……high],其中,pos下标所对应的数组元素的值就是进行划分的基准值key,所以在划分结束时还要将下标为pos的数组元素赋值 为 key。 (6)将划分得到的左右两部分A[low……pos-1]和A[pos+1……high]继续采用以上操作步骤进行划分,直到得到有序序列为止。 ```c #include #include #define N 10 int partition(int arr[], int low, int high) { int key; key = arr[low]; while (low < high) { while (low < high && arr[high] >= key) { high--; } if (low < high) { arr[low++] = arr[high]; } while (low < high && arr[low] <= key) { low++; } if (low < high) { arr[high--] = arr[low]; } } arr[low] = key; return low; } void quick_sort(int arr[], int start, int end) { int pos; if (start < end) { pos = partition(arr, start, end); quick_sort(arr, start, pos - 1); quick_sort(arr, pos + 1, end); } } int main(int argc, char *argv[]) { int i; int arr[N] = { 56, 21, 32, 200, 1, -23, 345, 5, 18, 333 }; printf("排序前: "); for (i = 0; i < N; i++) { printf("%d\t", arr[i]); } printf("\n"); printf("排序后: "); quick_sort(arr, 0, N - 1); for (i = 0; i < N; i++) { printf("%d\t", arr[i]); } printf("\n"); system("pause"); return 0; } ``` 运行结果: 排序前: 56 21 32 200 1 -23 345 5 18 333 排序后: -23 1 5 18 21 32 56 200 333 345 其中这之中巧妙的用了递归写法,从对象角度来看,没有生成新的对象,没有占用新的内存空间,而且快速排序比之前的冒泡排序算法从实际情况下要更快,当然极端情况下也可能一样,因为不管是冒泡排序法还是快速排序法的时间复杂度都是O(n^2^)。