快速排序简介
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列,是对冒泡排序的一种改进。时间复杂度为O(nlogn)。
快速排序的模拟过程可以看链接:QuickSortion
实现过程
为了比较容易地理解插入排序,我们可以列出一组数据,比如:
4, 5, 3, 7
对于快排的理解,建议自己先看快排模拟过程帮组理解
分析以上过程,快速排序算法几个实现要点:
1. 通过两个地址low, high实现函数递归,用于在键断裂后,对剩下的链再进行排序
2. 需要两个for循环,一个用于从 low 到 high 地址的值之间的比较,另一个用于从 high 到 low 地址的值之间的比较
3. 最重要的是,我们需要在键断裂后,对新形成的前后两个值进行比较然后交换彼此的值
代码实现
void quickSort(int *a, const int low, const int high) {
//在这里,出入的是高地址和低地址,而不是传入length
if (low < high) {
int h = high;
int j;
for (j = low; j < h; j++) {
if (a[j] > a[low]) {
for (h; h > j; h--) { //不选择用 high,而选择h值,这样我们就不会重复用到之前已经验证过比a[j]大的值了
if (a[h] < a[low]) {
exchange(a, j, h);
break;
}
}
}
}
if (a[low] > a[j])
exchange(a, low, j);
quickSort(a, h, high);
quickSort(a, low, j-1); //需要注意这里,j-1而不是j,由于之前的for循环已经增加1了
}
}
完整实现:
#include <stdio.h>
void print(const int *a, const int length) {
int i;
for (i = 0; i<length; i++) {
printf("%d ", a[i]);
}
putchar('\n');
}
void exchange(int *a, const int i, const int j) {
int tmp = *(a + i);
*(a + i) = *(a + j);
*(a + j) = tmp;
}
void quickSort(int *a, const int low, const int high) {
if (low < high) {
int h = high;
int j;
for (j = low; j < h; j++) {
if (a[j] > a[low]) {
for (h; h > j; h--) {
if (a[h] < a[low]) {
exchange(a, j, h);
break;
}
}
}
}
if (a[low] > a[j])
exchange(a, low, j);
print(a + low, high);
quickSort(a, h, high);
quickSort(a, low, j-1);
}
}
void main() {
const int length = 3;
int my_array[3] = { 5,4,6};
quickSort(my_array, 0, length-1);
print(my_array, length);
}
代码精简
void QuickSort(int a[], const int low, const int high) {
if (low< high){
int i = low, j = high, x = a[low];
while (i < j){
while(i < j && a[j]>= x) // 从右向左找第一个小于x的数
j--;
if(i < j)
a[i++] = a[j];
while(i < j && a[i]< x) // 从左向右找第一个大于等于x的数
i++;
if(i < j)
a[j--] = a[i];
}
a[i] = x;
QuickSort(a, low, i - 1);
QuickSort(a, i + 1, high);
}
}