面試官:快排會寫嗎?

快排能夠說是一道必知的常見面試題,同時也有多種實現方式。在這篇文章中,我使用的是隨機三路快排。面試

之因此使用隨機快速排序而不是普通的快排。是由於前者可使得數列有序的機率下降,從而使隨機快速排序平均速度是比快速排序要快的。具體的二者的性能差異能夠看下這篇文章:數組

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

相關文章
相關標籤/搜索