快速排序,从名字来看就够藐视一切了,不过经过测试,快速排序还是比较对得起这个名字的,速度还是比较快的,不过快速排序依然是一个不稳定排序,其平均时间复杂度为NlogN。
快速排序的基本思想是在一个数组中找一个元素为参考值,将大于它的元素放在一边,然后将小于它的元素放在另一边,这样其实就得到两个子数组,然后对子数组再分别找一个参考点,大于参考点的放在一边,小于的放在另一边,如此循环下去,所以在做的时候要非常注意循环的终止,判断条件非常重要。
在实现上,快排需要一个切分函数来处理大于或者小于参考点的元素的安放位置:
int QtSort::partition(int* pInput, int low, int high) { int i = low; int j = high + 1; int v = pInput[low]; while (true) { while (less(pInput[++i], v)) { if (i==high) { break; } } while (less(v, pInput[--j])) { if (j==low) { break; } } if (i >= j) { break; } int tmp = pInput[i]; pInput[i] = pInput[j]; pInput[j] = tmp; } int tmp = pInput[low]; pInput[low] = pInput[j]; pInput[j] = tmp; return j; }
有了切分函数之后还需要一个排序函数,排序函数就比较简单了,先调用切分函数得到参考点,然后分别对左边和右边进行递归调用就可以了:
void QtSort::quickSort(int* pInput, int low, int high) { if (high <= low) { return; } int j = partition(pInput, low, high); quickSort(pInput, low, j - 1); quickSort(pInput, j + 1, high); }
快速排序跟归并排序一样体现的是分治的思想。归并排序是将大数组拆分成小的数组,将小数组独立排序后再逐一归并回大数组,快排则是将大数组按参考值拆分成大于参考值和小于参考值的小数组,只要小数组都是有序的那么整个数组就是有序的。
泪眼注,临当去,
此时欲住已难住。
下楼复上楼,
楼头风吹雨。
风吹雨,草草离人语。
上善若水,为而不争。