public class FastSort {
public static void main(String[] args) {
int[] ints = {3, 4, 1, 5, 9, 6, 7, 2, 10, 6, 12, 1};
fastSort(ints, 0, ints.length - 1);
System.out.println(Arrays.toString(ints));
}
private static void fastSort(int[] ints, int start, int end) {
if (start < end) {
int pos = ints[start];
int low = start;
int high = end;
int temp;
while (low < high) {
while (low < high && ints[high] >= pos) {
high--;
}
while (low < high && ints[low] <= pos) {
low++;
}
if (low < high) {
temp = ints[high];
ints[high] = ints[low];
ints[low] = temp;
}
}
temp = ints[low];
ints[low] = pos;
ints[start] = temp;
fastSort(ints, start, low - 1);
fastSort(ints, low + 1, end);
}
}
}
首先,塊排是分治思想的體現,分治,分而治之.一般分爲三部分:分解爲子問題,解決子問題,合併.
T(n) = a(n/b) + f(n);
在塊排中,我們也是分治的思想,選取一個x,
1.將整個數組分爲小於等於x和大於等於x兩部分.
2.分而治之,將小於x的部分作爲子問題遞歸求解,將大於x的部分也進行同樣的操作.
3.進行完操作之後,然後將之與x進行合併…
T(n) = T(a|a<=x) + x +T (b|b>=x) ;
在塊排中,我們將數組分爲兩部分,可以選取一個數作爲軸標準大小x,通常選取第一個元素,然後根據軸大小,向中間推進.在會和的時候,確定軸的位置.
1.在右邊遇到小於軸的元素的時候停止
while (low < high && ints[high] >= pos) {
high--;
}
2.在左邊遇到大於軸的元素的時候停止
while (low < high && ints[low] <= pos) {
low++;
}
3.交換兩個元素,這樣就做到了軸兩邊的元素大小符合要求.
if (low < high) {
temp = ints[high];
ints[high] = ints[low];
ints[low] = temp;
}
4.重複1-3操作,直到左index 等於右index.
5.這個時候將軸標的值x和左index互換,這樣左邊<=x<=右邊了.
temp = ints[low];
ints[low] = pos;
ints[start] = temp;
現在存在一個問題,怎麼保證賦給x原位置的值小於X呢?
- 跳出循環只有兩種可能:
- 右邊遇到了比X小的數字,而左邊的index上恰恰等於這個數字,這個時候是正確的
- 右邊在遞減的時候,low=high了,因爲每次循環開始的時候,low的位置一定是小於x的,所以這個時候也是正確的.
當然,這個是在右邊遞減在前的時候,如果左邊遞增在前,那麼就不成立了,最後的low上的值的大小就不太正確了.