分析
快排相當於在數組最左邊和數組最右邊定義兩個指針,將數組第一個元素定義爲key。
左指針負責將定位到的<key的元素全部丟到右邊,右指針負責將定位到的<=key的元素全部丟到左邊。
這樣一來,當循環結束後,將key值和兩個指針重疊的數值進行交換後,所有左邊的元素都<=key,而所有右邊的元素都>key。然後再重複以上做法,將key左邊的數組進行同樣的算法排序,右邊也一樣。
示例流程
這裏我們以{1,2,4,5,7,4,5,3,0}爲例進行分析。首先對{1,2,4,5,7,4,5,3,0}進行排序:
1.一開始i指向a[0],j指向a[a.length-1],key=a[0]
-
當(a[j] > key && i < j) j--,即左移指針;
-
當(a[i] <= key && i < j) i++,即右移指針;
-
當i < j時,交換a[i]和a[j]位置;
-
當i = j,觸發條件直接跳出while循環,並進行key值調整。
key
1 2 4 5 7 4 5 3 0
i j
第一次while循環(最外圈的while循環):
1 2 4 5 7 4 5 3 0
i j
當i < j時,交換a[i]和a[j]位置:
1 0 4 5 7 4 5 3 2
i j
第二次while循環:
key
1 0 4 5 7 4 5 3 2
i j
1 0 4 5 7 4 5 3 2
i
j
i = j,觸發條件直接跳出while循環,進行key值調整:
0 1 4 5 7 4 5 3 2
i
j
key
這樣一來,key左邊的都是小於key的,而key右邊的都是大於key的。
再進行左邊{0}和右邊{4,5,7,4,5,3,2}兩個數字的快排。流程如上。
2.對左邊數組{0}排序,i,j皆爲指針。
key
0
i
j
i = j,觸發條件直接跳出while循環,進行key值調整。因爲 i=j,所以交換後0還是0
3.對左邊數組{4,5,7,4,5,3,2}排序,i,j皆爲指針。
-
當(a[j] > key && i < j) j--,即左移指針;
-
當(a[i] <= key && i < j) i++,即右移指針;
-
當i < j時,交換a[i]和a[j]位置;
-
當i = j,觸發條件直接跳出while循環,並進行key值調整。
key
4 5 7 4 5 3 2
i j
第一次while循環:
4 5 7 4 5 3 2
i j
i < j時,交換a[i]和a[j]位置:
4 2 7 4 5 3 5
i j
4 2 7 4 5 3 5
i j
i < j時,交換a[i]和a[j]位置:
4 2 3 4 5 7 5
i j
4 2 3 4 5 7 5
j
i
當i = j,觸發條件直接跳出while循環,並進行key值調整。
現在4左邊的數字都<=4,4右邊的都>4,分爲了{4,2,3}和{5,7,5}兩個數組,對左右進行分別採用上面方法一樣遞歸排序即可。下面省略了分析流程。
代碼:
package com.quicksort;
import java.util.Arrays;
public class QuickSort {
public static void main(String[] args) {
int[] a = {1, 2, 4, 5, 7, 4, 5 ,3 ,9 ,0};
System.out.println(Arrays.toString(a));
quickSort(a);
System.out.println(Arrays.toString(a));
}
public static void quickSort(int[] a) {
if(a.length>0) {
quickSort(a, 0 , a.length-1);
}
}
private static void quickSort(int[] a, int low, int high) {
//1,找到遞歸算法的出口
if( low > high) {
return;
}
//2, 存
int i = low;
int j = high;
//3,key
int key = a[ low ];
//4,完成一趟排序
while( i< j) {
//4.1 ,從右往左找到第一個小於key的數
while(i<j && a[j] > key){
j--;
}
// 4.2 從左往右找到第一個大於key的數
while( i<j && a[i] <= key) {
i++;
}
//4.3 交換
if(i<j) {
int p = a[i];
a[i] = a[j];
a[j] = p;
}
}
// 4.4,調整key的位置
int p = a[i];
a[i] = a[low];
a[low] = p;
//5, 對key左邊的數快排
quickSort(a, low, i-1 );
//6, 對key右邊的數快排
quickSort(a, i+1, high);
}
}