亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

1. 前言

排序算法是數據結構中最基礎的算法,快速排序則是面試中最常見的排序算法。無論是校招面試還是社招面試,快速排序算法的出現頻率遠高于其他算法,而且經常會要求候選人白板手寫實現算法??焖倥判蛩惴ǖ暮诵氖欠种翁幚?,重點是分析時間復雜度。

2. 快速排序算法

面試官提問:快速排序算法是怎么實現的?能手寫實現一個快排算法嗎?

題目解析

為了實現bug free(基本沒有邏輯缺陷)的白板編程,候選人可以將解決這個題目的過程分為兩個步驟:

(1)分析快速排序算法的步驟,并且編碼實現;
(2)完成編碼后,使用一個小規模的數據作為測試樣例,模擬算法流程驗證代碼邏輯是否符合預期。

2.1 快速排序步驟

快速排序算法的核心是分治算法,所謂分治(Divide and Conquer)就是將一個復雜的問題分成兩個或者多個相同或者相似的子問題,再把這些子問題分成多個相同或者相似的子問題,直到子問題能夠被簡單求解,把子問題的解合起來就是原始問題的解。

快排的分治思維在于將大的數組拆分為兩個需要排序的左右子數組,再對子數組套用相同算法,直到子樹組只有一個數字,一個數字的數組本身就是有序的,構成了原子問題的解??炫诺暮诵牟襟E拆分為:

(1)選擇基準:對于數組 A,選擇一個數字作為基準值(pivot),習慣選擇數組第一個元素作為 pivot;
(2)構造分區:定義 left 和 right 左右指針,將小于基準的元素移動到左邊,將大于基準的元素移動到右邊;
(3)遞歸求解:對于基準左邊的數組 A1、基準右邊的數組 A2 重復第一步和第二步,直到所有的子樹組已經滿足排序性質(子數組為空或者子樹組只有一個元素)。

快速排序的算法實現代碼以及解析,示例:

    public void quicksort(int[] A,int left, int right) {
        //1. 遞歸終止條件,如果不構成數組結束算法
        if(left > right)
            return;
        int i, j, t, pivot;
        //2. 選擇第一個元素作為pivot
        pivot = A[left];
        i = left;
        j = right;
        while(i != j) {
            //3.1 這里要注意順序,必須先從右邊開始找到第一個比pivot小的數
            while(A[j] >= pivot && i < j)
                j--;
            //3.2 然后從左邊找到第一個比pivot大的數字
            while(A[i] <= pivot && i < j)
                i++;
            //3.3 交換兩個數在數組中的位置
            if(i < j) {
                t = A[i];
                A[i] = A[j];
                A[j] = t;
            }
        }
        //4. 最終將基準數歸位
        A[left] = A[i];
        A[i] = pivot;
        //遞歸處理左邊的分數組
        quicksort(A,left, i-1);
        //遞歸處理右邊的分數組
        quicksort(A,i+1, right);
    }

2.2 小型數組模擬

下面我們使用一個小規模的數組模擬快速排序的過程,原始數組A的順序是22、11、44、10、33。

(1)首先給定初始值:pivot = nums[left] = 22,left=0,right=4。

index 0 1 2 3 4
數組值 22 11 44 10 33
指針 left right

(2)從右到左找到 index=3 的位置,nums[3] 比 pivot 小;從左到右找到 index=2 的位置,nums[2] 比 pivot 大。

index 0 1 2 3 4
數組值 22 11 44 10 33
指針 left i j right

(3)交換坐標 i 和 j 所在的數組值。

index 0 1 2 3 4
數組值 22 11 10 44 33
指針 left i,j right

(3)坐標 i 和 j 碰頭,本次查找結束,交換 pivot 的值和 nums[i] 的值。

index 0 1 2 3 4
數組值 10 11 22 44 33
指針 left i,j right

(4)本次查詢完全結束,對坐標[0,1]的子數組和坐標[3,4]的子樹組進行相同的遞歸操作,結束之后,數組A得到結果10、11、22、33、44。

2.3 快排考察點

關于快排,候選人需要注意幾個關鍵的考察點:

(1)快排的平均時間復雜度為O(N*logN),最壞狀態下時間復雜度為O(N^2),一般不會涉及具體的數學證明;
(2)快排不是穩定排序算法,例如原始數組存在兩個相同的數值,排序可能會交換兩個值的順序;
(3)快速排序的核心思路是分治算法,實現方式是遞歸。

3. 小結

本章節介紹了面試最常見的排序算法算法:快排的算法思路以及使用 Java 實現了一個快排的算法模板。候選人可以使用小規模的數組測試現場編寫的算法是否符合預期,特別需要注意快排的時間復雜度。