快速排序时间复杂度在最好的情况下是O(n log n),在平均情况下是O(n log n),在最坏的情况下是O(n ^ 2)。但是因为它在大多数输入的平均情况下具有最佳性能,所以快速排序通常被认为是“ 最快 ”的排序算法。另外,快速排序算法是不稳定的,即如果两个元素数值相同,快排结果后位置可能不同。
快速排序算法是分治策略的一种应用,其核心思想是把输入的数组从左向右数的大于基准数的元素 与 从右往左的小于基准数的元素 交换(以第一个元素为基准数pivot),然后递归地将左右两区域进一步排序,直到 left 不再 < right。
快速排序(c++代码示例已运行通过)
#include <iostream>
using namespace std;
int partation(int a[], int left, int right);
void quickSort(int a[],int left, int right) {
if(left < right) {
int anchor = partation(a, left, right);
quickSort(a, left, anchor - 1);
quickSort(a, anchor + 1, right);
}
}
int partation(int a[], int left, int right){
int i = left, j = right + 1;
int pivot = a[left];
//把小于pivot的元素交换到左边,大于pivot的元素到右边
while(true){
//即当a[i]小于pivot时且i<j时,下标i不断右移(直到a[i]>=pivot)时,交换a[i],a[j]
while(a[++i] < pivot && i < j);
while(a[--j] > pivot);
if (i >= j)
break;
swap(a[i], a[j]);
}
a[left] = a[j];
a[j] = pivot;
//返回下标j为划分点
return j;
}
int main(){
int a[] = {13, 22, 45, 11, 73, 26, 38};
int n = 7;
quickSort(a, 0, n - 1);
for(int i = 0; i < n; i++)
cout << a[i] << ' ';
return 0;
}
以上代码我解释一下:
partation的作用主要是将小于pivot的元素放在数组左半边,将大于pivot的元素放在右半边。然后quickSort将以anchor划分开的左右区域进一步进行排序,如此一直递归地调用,直到下标left跟right相撞。
这里注意一个,int pivot =a[left],基准数的选择是任意的。它可以是数组的第一个元素,数组的最后一个元素,甚至是随机元素!
快排性能取决于划分的对称性,分治法的性能经大量经验表明当划分为接近对称时,性能最优,所以快速排序的基准数有时会用一个random函数特意的挑选随机元素以求该元素是接近元素中间值的。但其实我觉得没什么卵用,因为如果数组元素真的是无序的,那么不管是哪里的元素应该效果都是一样的。所以除非在数据显现出一定的规律让你觉得最左最右的元素会使划分严重不对称时,可以考虑用随机函数。