快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。
通过一趟排序将待排记录分割成独立的两个部分,一部分的关键字比另一部分的关键字小,则可以分别对两部分记录继续进行排序。

package sort;
public class QuickSort {
private static int count = 1;
public static void main(String[] args) {
int[] o = {49, 38, 45, 27, 46, 13, 27, 8};
System.out.print("排序前: ");
for (int t : o) {
System.out.print(t);
System.out.print(" ");
}
System.out.println();
// 算法部分
int left = 0;
int right = o.length - 1;
quickSort(o, left, right);
System.out.print("排序后: ");
for (int t : o) {
System.out.print(t);
System.out.print(" ");
}
System.out.println();
}
private static void quickSort(int[] arr, int left, int right) {
if (left < right) {
int partitionIndex = partition(arr, left, right);
quickSort(arr, left, partitionIndex - 1);
quickSort(arr, partitionIndex + 1, right);
} else {
count++;
}
}
private static int partition(int[] arr, int left, int right) {
// left位置的记录就是pivot,index代表比pivot小的下标
int index = left + 1;
System.out.print("第" + count + "趟pivot=" + arr[index - 1] + ",排序后: ");
for (int i = index; i <= right; i++) {
if (arr[i] < arr[left]) {
swap(arr, i, index);
index++;
}
}
swap(arr, left, index - 1);
for (int t : arr) {
System.out.print(t);
System.out.print(" ");
}
System.out.println();
count++;
return index - 1;
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
执行结果
排序前: 49 38 45 27 46 13 27 8
第1趟pivot=49,排序后: 8 38 45 27 46 13 27 49
第2趟pivot=8,排序后: 8 38 45 27 46 13 27 49
第4趟pivot=38,排序后: 8 27 27 13 38 45 46 49
第5趟pivot=27,排序后: 8 13 27 27 38 45 46 49
第8趟pivot=45,排序后: 8 13 27 27 38 45 46 49
排序后: 8 13 27 27 38 45 46 49
经过上述一趟快速排序,我们只确定了一个元素的最终位置,我们最终需要经过 n n n趟快速排序才能将一个含有 n n n个数据元素的序列排好序,下面我们来分析其时间复杂度.
设
n
n
n 为待排序数组中的元素个数,
T
(
n
)
T(n)
T(n)为算法需要的时间复杂度则
T
(
n
)
=
{
D
(
1
)
n
≤
1
D
(
n
)
+
T
(
I
1
)
+
T
(
I
2
)
n
>
1
T(n)= {D(1)n≤1D(n)+T(I1)+T(I2)n>1
T(n)={D(1)D(n)+T(I1)+T(I2)n≤1n>1
其中
D
(
n
)
=
n
−
1
D(n)=n−1
D(n)=n−1 ,是一趟快排需要的比较次数,一趟快排结束后将数组分成两部分
I
1
I_1
I1 和
I
2
I_2
I2。
最好的情况是,每一次划分都正好将数组分成长度相等的两半
T
(
n
)
=
{
D
(
1
)
n
≤
1
D
(
n
)
+
T
(
n
2
)
+
T
(
n
2
)
n
>
1
T(n)= {D(1)n≤1D(n)+T(n2)+T(n2)n>1
T(n)={D(1)D(n)+T(2n)+T(2n)n≤1n>1
∴ T ( n ) = D ( n ) + 2 T ( n 2 ) = D ( n ) + 2 D ( n 2 ) + 2 T ( n 4 ) . . . = D ( n ) + 2 D ( n 2 ) + 4 D ( n 4 ) + . . . + 2 k D ( n 2 k ) = n − 1 + 2 ( n 2 − 1 ) + 4 ( n 4 − 1 ) + . . . + 2 k ( n 2 k − 1 ) = ( n − 1 ) + ( n − 2 ) + ( n − 4 ) + . . . + ( n − 2 k ) ⟹ ∑ k = 1 n n − 2 k = k n − 2 k + 1 ∵ k = l o g 2 n ∴ 原式 = n l o g 2 n − 2 n + 1 ⟹ O ( n l o g 2 n ) ∴ ∴T(n)=D(n)+2T(2n)=D(n)+2D(2n)+2T(4n)...=D(n)+2D(2n)+4D(4n)+...+2kD(2kn)=n−1+2(2n−1)+4(4n−1)+...+2k(2kn−1)=(n−1)+(n−2)+(n−4)+...+(n−2k)⟹k=1∑nn−2k=kn−2k+1∵k=log2n∴原式=nlog2n−2n+1⟹O(nlog2n)
最坏情况下,每一次划分都将数组分成了
0
0
0和
n
−
1
n-1
n−1两部分
T
(
n
)
=
{
D
(
1
)
n
≤
1
D
(
n
)
+
T
(
n
−
1
)
+
T
(
0
)
n
>
1
T(n)= \begin{cases} \vcenter D(1) &{n \leq 1} \\ D(n)+T(n-1)+T(0) &{n >1 } \end{cases}
T(n)={D(1)D(n)+T(n−1)+T(0)n≤1n>1
∴ T ( n ) = D ( n ) + 2 T ( n − 1 ) = D ( n ) + D ( n − 1 ) + T ( n − 2 ) . . . = D ( n ) + D ( n − 1 ) + D ( n − 2 ) + . . . + D ( 1 ) = ( n − 1 ) + ( n − 2 ) + ( n − 3 ) + . . . + 0 ⟹ ∑ k = 0 n k = n ( n − 1 ) 2 原式 = n ( n − 1 ) 2 ⟹ O ( n 2 ) \begin{aligned} \therefore T(n)&=D(n)+2T(n-1) \\ &=D(n)+D(n-1)+T(n-2) \\ &.\\ &.\\ &.\\ &=D(n)+D(n-1)+D(n-2)+...+D(1) \\ &=(n-1)+(n-2)+(n-3)+...+0 \\ &\implies \displaystyle \sum_{k=0}^{n}k=\frac{n(n-1)}{2} \\ 原式&=\frac{n(n-1)}{2} \implies \boxed{O(n^2)}\\ \end{aligned} ∴T(n)原式=D(n)+2T(n−1)=D(n)+D(n−1)+T(n−2)...=D(n)+D(n−1)+D(n−2)+...+D(1)=(n−1)+(n−2)+(n−3)+...+0⟹k=0∑nk=2n(n−1)=2n(n−1)⟹O(n2)
任意一种划分情况出现的概率都相等
A
l
l
=
{
I
1
=
0
I
2
=
n
−
1
I
1
=
1
I
2
=
n
−
2
.
.
.
I
1
=
n
−
1
I
2
=
0
All= \begin{cases} I_1=0 & I_2=n-1 \\ I_1=1 & I_2=n-2 \\ . \\ . \\ . \\ I_1=n-1 & I_2=0 \\ \end{cases}
All=⎩
⎨
⎧I1=0I1=1...I1=n−1I2=n−1I2=n−2I2=0
∴ T a v g ( n ) = D ( n ) + 1 n ∗ ∑ i = 0 n − 1 T a v g ( i ) + T a v g ( n − i ) = D ( n ) + 2 n ∗ ∑ i = 0 n − 1 T a v g ( i ) T a v g ( n − 1 ) = D ( n − 1 ) + 2 n − 1 ∗ ∑ i = 0 n − 2 T a v g ( i ) n T a v g ( n ) − ( n − 1 ) T a v g ( n − 1 ) = n D ( n ) + 2 ∑ i = 0 n − 1 T a v g ( i ) − ( n − 1 ) D ( n − 1 ) − 2 ∗ ∑ i = 0 n − 2 T a v g ( i ) = n D ( n ) − ( n − 1 ) D ( n − 1 ) + 2 T a v g ( n − 1 ) = n ( n − 1 ) − ( n − 1 ) ( n − 2 ) + 2 T a v g ( n − 1 ) = 2 ( n − 1 ) + 2 T a v g ( n − 1 ) 移项得 n T a v g ( n ) = 2 ( n + 1 ) + 2 T a v g ( n − 1 ) + ( n − 1 ) 2 T a v g ( n − 1 ) = 2 ( n + 1 ) + ( n + 1 ) 2 T a v g ( n − 1 ) 等式两边同时除以 n ( n + 1 ) 得 T a v g ( n ) n + 1 = T a v g ( n − 1 ) n + 2 ( n − 1 ) n ( n + 1 ) 令 B ( n ) = T a v g ( n ) n + 1 得 B ( n ) = B ( n − 1 ) + 2 ( n − 1 ) n ( n + 1 ) = B ( n − 2 ) + 2 ( n − 2 ) n ( n − 1 ) + 2 ( n − 1 ) n ( n + 1 ) . . . = B ( 1 ) + ∑ i = 1 n 2 ( i − 1 ) i ( i + 1 ) = B ( 1 ) + ∑ i = 1 n 2 ( i + 1 ) − 4 i ( i + 1 ) = ∑ i = 1 n [ 2 i − 4 i ( i + 1 ) ] ∵ ∑ i = 1 n 4 i ( i + 1 ) = 4 ∑ i = 1 n [ i + 1 − i i ( i + 1 ) ] = 4 ∑ i = 1 n [ 1 i − 1 i ( i + 1 ) ] = 4 [ 1 − 1 n + 1 ] = 4 n n + 1 ∵ ∑ i = 1 n 1 i ≈ 0.577216+ln(n) ∴ B ( n ) = 2 ∗ 0.577216 + 2 ∗ l n ( n ) + 4 n n + 1 代回 B ( n ) = T a v g ( n ) n + 1 T a v g ( n ) = 2 ( n + 1 ) l n ( n ) − 4 n + 2 ∗ 0.577216 ( n + 1 ) ⟹ O ( n l o g 2 n ) \begin{aligned} \therefore T_{avg}(n)&=D(n)+\frac{1}{n}*\displaystyle \sum_{i=0}^{n-1}T_{avg}(i)+T_{avg}(n-i) \\ &=D(n)+\frac{2}{n}*\displaystyle \sum_{i=0}^{n-1}T_{avg}(i) \\ T_{avg}(n-1)&=D(n-1)+\frac{2}{n-1}*\displaystyle \sum_{i=0}^{n-2}T_{avg}(i)\\ nT_{avg}(n)-(n-1)T_{avg}(n-1)&= nD(n)+2\displaystyle \sum_{i=0}^{n-1}T_{avg}(i)-(n-1)D(n-1)-2*\displaystyle \sum_{i=0}^{n-2}T_{avg}(i) \\ &=nD(n)-(n-1)D(n-1)+2T_{avg}(n-1) \\ &=n(n-1)-(n-1)(n-2)+2T_{avg}(n-1) \\ &=2(n-1)+2T_{avg}(n-1) \\ 移项得 \\ nT_{avg}(n) &= 2(n+1)+2T_{avg}(n-1)+(n-1)2T_{avg}(n-1) \\ &= 2(n+1)+(n+1)2T_{avg}(n-1) \\ 等式两边同时除以n(n+1)得 \\ \frac{T_{avg}(n)}{n+1}&=\frac{T_{avg}(n-1)}{n}+\frac{2(n-1)}{n(n+1)} \\ 令B(n)=\frac{T_{avg}(n)}{n+1} 得\\ B(n)&=B(n-1)+\frac{2(n-1)}{n(n+1)} \\ &=\boxed{B(n-2)+\frac{2(n-2)}{n(n-1)}}+\frac{2(n-1)}{n(n+1)} \\ .\\ .\\ .\\ &=B(1)+\displaystyle \sum_{i=1}^{n}\frac{2(i-1)}{i(i+1)} \\ &=B(1)+\displaystyle \sum_{i=1}^{n}\frac{2(i+1)-4}{i(i+1)} \\ &=\displaystyle \sum_{i=1}^{n}[\frac{2}{i}-\frac{4}{i(i+1)}] \\ \because \displaystyle \sum_{i=1}^{n}\frac{4}{i(i+1)}&= 4\displaystyle \sum_{i=1}^{n}[\frac{i+1-i}{i(i+1)}] \\ &= 4\displaystyle \sum_{i=1}^{n}[\frac{1}{i}-\frac{1}{i(i+1)}] \\ &= 4[1-\frac{1}{n+1}]=\boxed{4\frac{n}{n+1}}\\ \because \displaystyle \sum_{i=1}^{n}\frac{1}{i}&\approx \colorbox{aqua}{0.577216+ln(n)} \\ \therefore B(n)&=2*0.577216+2*ln(n)+4\frac{n}{n+1} \\ 代回B(n)=\frac{T_{avg}(n)}{n+1} \\ T_{avg}(n)&=2(n+1)ln(n)-4n+2*0.577216(n+1) \implies \boxed{O(nlog_2^n)} \\ \end{aligned} ∴Tavg(n)Tavg(n−1)nTavg(n)−(n−1)Tavg(n−1)移项得nTavg(n)等式两边同时除以n(n+1)得n+1Tavg(n)令B(n)=n+1Tavg(n)得B(n)...∵i=1∑ni(i+1)4∵i=1∑ni1∴B(n)代回B(n)=n+1Tavg(n)Tavg(n)=D(n)+n1∗i=0∑n−1Tavg(i)+Tavg(n−i)=D(n)+n2∗i=0∑n−1Tavg(i)=D(n−1)+n−12∗i=0∑n−2Tavg(i)=nD(n)+2i=0∑n−1Tavg(i)−(n−1)D(n−1)−2∗i=0∑n−2Tavg(i)=nD(n)−(n−1)D(n−1)+2Tavg(n−1)=n(n−1)−(n−1)(n−2)+2Tavg(n−1)=2(n−1)+2Tavg(n−1)=2(n+1)+2Tavg(n−1)+(n−1)2Tavg(n−1)=2(n+1)+(n+1)2Tavg(n−1)=nTavg(n−1)+n(n+1)2(n−1)=B(n−1)+n(n+1)2(n−1)=B(n−2)+n(n−1)2(n−2)+n(n+1)2(n−1)=B(1)+i=1∑ni(i+1)2(i−1)=B(1)+i=1∑ni(i+1)2(i+1)−4=i=1∑n[i2−i(i+1)4]=4i=1∑n[i(i+1)i+1−i]=4i=1∑n[i1−i(i+1)1]=4[1−n+11]=4n+1n≈0.577216+ln(n)=2∗0.577216+2∗ln(n)+4n+1n=2(n+1)ln(n)−4n+2∗0.577216(n+1)⟹O(nlog2n)
快速排序的空间复杂度取决于分划基准的选择,每次都选在中间, O ( l o g 2 n ) O(log_2^n) O(log2n)若基本有序,退化为冒泡,栈的深度 O ( n ) O(n) O(n)。
O ( l o g 2 n ) O(log_2^n) O(log2n)就是递归的深度,递归的时候使用的栈空间稍微优化一点的快排,比如取首尾中三个数据,取其中间的值作为划分标准,不会出现退化到冒泡的可能。
计算参考:https://zhuanlan.zhihu.com/p/341201904