算法介绍
由C.A.R.Hoare在1962年提出,因为此算法而获得图灵奖。它是一种递归算法,核心思想是:先找出一个数的应该在的位置,将数列分为左右两部分,左右两部分分别进行排序。
图片示例
我们先找到 K 的位置,i 指针先向后移动,所指元素如果比K大,就停止,此时再由 j 由队尾向前遍历,如果 j 指向元素比K小,j 停止移动,此时将 i 和 j 指向元素对调。
比如:
此时 i 指向元素R比 K 大,j 指向元素C比K小 ,对调R,C。
此时 i j 根据上述规则 继续移动,一直到 指针 j 超过了i ,K 和 j 对调
此时K已经在位置上了,将数列分为左右两边,左右再进行递归排序
实现代码
//主方法
private static void sort(Comparable[] a, int lo, int hi) {
if (lo >= hi) {
return;
}
int j = partition(a, lo, hi);
sort(a, 0, j - 1);
sort(a, j + 1, hi);
}
private static int partition(Comparable[] a, int lo, int hi) {
int i = lo ;
int j = hi+1;
//a[lo]即为第一个元素,先将它的位置找到
while (true){
// 找到 i ,i 小于 a[lo]的话,继续移动
while (less(a[++i],a[lo])){
if(i == hi){
break;
}
}
// j 也类似
while (less(a[lo],a[--j])){
if(j==lo){
break;
}
}
// 两指针擦肩而过的话,就跳出循环
if(i>=j){
break;
}
// 交换 i和j
change(a,i,j);
}
// 交换 lo和j
change(a,lo,j);
return j;
}
复杂度推导
假设 Cn 为快速排序N个数需要比较的次数。
找到第一个数所在位置,我们需要比较 N+1次。指针 i 和 j 每移动一次就需要比较一次,一共是 N-1次, 加上相遇比较一次 ,擦肩而过还需要比较一次,所以是N+1次。
这个数会把数组分割成各种情况,会分割成(1,n-1),(2,n-2),(3,n-3).......(n-1,1)各种情况,所以Cn的表达式如下:
平均复杂度为1.39NlgN
缺点与不足
1. 为了保证性能,快速排序前一定要打乱数组顺序,正序下,快排复杂度需要1/2
乘以n的二次方
2. 如果数组存在大量相同的数,性能也是平方级的
第一次写博客,这是我的理解,如果有误请指出,我会立即纠正,谢谢
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。