Quick Sort使用了Divide and Concur的思想: 找一个基准数, 把小于基准数的数都放到基准数之前, 把大于基准数的数都放到基准数之后
Worst case: O(n^2)
Average case: O(nlogN)
步骤:
初始的数组 Array a[]:
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
51 |
73 |
52 |
18 |
91 |
7 |
87 |
73 |
48 |
3 |
基准数: X = a[0] = 51
i 的值: i = 0
j 的值: j = 9 (a.length)
Step 1:
- 从后 (j 位置)向前找比X小的数, 填坑 (坑就是a[0])
- 当 j = 9 时, a[9] < 51, 所以把a[9] 放到a[0] 去 (a[0] = a[9], i++)
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
3 |
73 |
2 |
18 |
91 |
7 |
87 |
73 |
48 |
3 |
此时 i = 1, j = 9
Step 2:
- 从i位置向后找比X (51) 大的数, 填坑 (坑就是a[9])
- 当 i = 1 的时候, a[1] > 51, 所以把a[1] 放到 a[9] 去 (a[9] = a[1], j--)
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
3 |
73 |
2 |
18 |
91 |
7 |
87 |
73 |
48 |
73 |
此时 i = 1, j = 8
Step 3:
- 从j位置向前找比X (51) 小的数, 填坑 (坑就是a[1])
- 当 j = 8 的时候, a[8] < 51, 所以把a[8] 放到 a[1] 去 (a[1] = a[8], i++)
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
3 |
48 |
2 |
18 |
91 |
7 |
87 |
73 |
48 |
73 |
此时 i = 2, j = 8
Step 4:
- 从i位置向后找比X (51) 大的数, 填坑 (坑就是a[8], 此时 i = 2)
- 当 i = 4 的时候, a[4] > 51, 所以把a[4] 放到 a[8] 去 (a[8] = a[4], j--)
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
3 |
48 |
2 |
18 |
91 |
7 |
87 |
73 |
91 |
73 |
此时 i = 4, j = 7
Step 5:
- 从j位置向前找比X (51) 小的数, 填坑 (坑就是a[4], 此时 j = 7)
- 当 j = 5 的时候, a[5] = 7 < 51, 所以把a[5] 放到 a[4] 去 (a[4] = a[5], i++)
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
3 |
48 |
2 |
18 |
7 |
7 |
87 |
73 |
91 |
73 |
此时 i = 5, j = 5
因为 i = j, 循环结束, 将X填坑放到a[5] 里
Step 6:
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
3 |
48 |
2 |
18 |
7 |
51 |
87 |
73 |
91 |
73 |
可以看到, a[i]之前的数都是小于a[i]的, a[i]之后的数都是大于a[i]的
之后对a[0 - 4]和a[6-9]继续进行之前的步骤
Quick Sort的代码:
1 public int pivot(int[] A, int left, int right){ 2 int p = A[left]; 3 while(left < right){ 4 while(left < right && A[right] >= p) 5 right--; 6 if(left < right){ 7 A[left] = A[right]; 8 left++; 9 } 10 while(left < right && A[left] <= p) 11 left++; 12 if(left < right){ 13 A[right] = A[left]; 14 right--; 15 } 16 } 17 A[left] = p; 18 return left; 19 } 20 21 public void qs(int[] A, int left, int right){ 22 int i; 23 if(left < right){ 24 i = pivot(A, left, right); 25 qs(A, left, i - 1); 26 qs(A, i + 1, right); 27 } 28 }