快排能夠說是一道必知的常見面試題,同時也有多種實現方式。在這篇文章中,我使用的是隨機三路快排。面試
之因此使用隨機快速排序而不是普通的快排。是由於前者可使得數列有序的機率下降,從而使隨機快速排序平均速度是比快速排序要快的。具體的二者的性能差異能夠看下這篇文章:數組
blog.csdn.net/haelang/art…bash
talk id cheap,show the code。一共 20+ 行代碼,每行代碼都有註釋。其中交換數組元素位置,打印元素的方法我就沒貼了,代碼太長大家也不方便看。微信
PS:代碼下面有執行流程圖,結合代碼來看比較容易理解。less
public static void main(String[] args) {
// 測試數據
int[] arr = new int[]{5, 3, 6, 4};
// 執行快排
quickSort(arr, 0, arr.length - 1);
// 打印數組元素
printArray(arr);
}
private static void quickSort(int[] arr, int l, int r) {
if (l < r) {
// 隨機取須要排序的數組中的一個元素和數組的最後一個元素交換,做爲劃分值
swap(arr, l + (int) (Math.random() * (r - l + 1)), r);
// 獲得數組元素中等於劃分值的區域
int[] part = partition(arr, l, r);
// 小於等於劃分值的區域
quickSort(arr, l, part[0] - 1);
// 大於劃分值的區域
quickSort(arr, part[1] + 1, r);
}
}
private static int[] partition(int[] arr, int l, int r) {
// 初始化小於等於劃分值區域的當前下標,默認是數組第一個元素的前一個位置
int less = l - 1;
// 初始化大於劃分值區域的當前下標,默認是數組最後一個元素的位置,同時也是劃分值的位置,但該值並不屬於大於劃分值的區域,因此要在最後進行移動
int more = r;
// 當前下標小於大於劃分值區域的下標時
while (l < more) {
// 當前值比劃分值小,當前值和小於等於劃分值區域的右邊第一個值進行交換,小於等於劃分值區域右移1個下標,當前下標+1
if (arr[l] < arr[r]) {
swap(arr, l++, ++less);
// 當前值比劃分值大,當前值和大於劃分值區域的左邊第一個值進行交換,大於劃分值的區域左移1個下標
} else if (arr[l] > arr[r]) {
swap(arr, l, --more);
// 當前值等於劃分值,當前下標+1
} else {
// 當前下標+1
l++;
}
}
// 將劃分值和大於劃分值區域中,最接近劃分值區域的元素交換。至此完成全部值的區域劃分
swap(arr, more, r);
// 返回等於劃分值的區域
return new int[]{less + 1, more};
}
複製代碼
下面我會畫個流程圖幫你們理解一下,測試數據和代碼同樣。dom
假設代碼執行完 13 行後,測試數據的順序依舊不變,即爲 {5,3,6,4}。性能
接下來在執行 partition() 方法的過程當中,數組元素的狀況以下圖所示(靈魂寫手求輕噴) 測試
好了,以上就是本文的所有內容,咱們下篇文章再見,捂臉逃~ui
PS:本文原創發佈於微信公衆號「不僅Java」,後臺回覆「Java」,送你 13 本 Java 經典電子書。公衆號專一分享 Java 乾貨、讀書筆記、成長思考spa