快速選擇(模板)

快速選擇原理如下,選擇第k大的數字:

我們在快速選擇的時候,也同樣用了劃分的思想,隨機選擇一箇中軸,雙指針i, j,指針i從左往右掃描,指針j從右往左掃描,如果i < j 則進行交換,並且繼續循環,直到遇到中軸,這時候我們的i和j均爲中軸(理由:因爲i,j相等),如果數字在中軸的左邊,則向左遞歸,如果數字在中軸的右邊則向右遞歸。

分析複雜度分析,剛開始的一個循環找中軸,用掉了n次,第二次循環只能找左邊的中軸或者右邊的中軸,用了n/2次,無限循環下去,直到極限,表達式如下

\[n + n/2 + n/4 + n/8 ...\\ 令 Sn = n + n/2 + n/4 + n/8 ...\\ 則 1/2 * Sn = n/2 + n/4 + n/8 ... \\ 上述兩式子相減得到 1/2 * Sn = n, 則 Sn = 2n \]

時間複雜度推導出T(2n),結果爲O(n)的複雜度。

int quick_select(int *q, int l, int r, int k) {
    if (l == r) return q[l];
    int i = l - 1, j = r + 1, x = q[l + r >> 1];
    while (i < j) {
        do i++ ; while (q[i] < x);
        do j-- ; while (q[j] > x);
        if (i < j) swap(q[i], q[j]);
    }
    if (k <= j - l + 1) return quick_select(q, l, j, k);
    return quick_select(q, j + 1, r, k - (j - l + 1));
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章