快速排序模板

2022-05-02 06:42:09 字數 1909 閱讀 5592

快排最關鍵的位置就是關鍵點的選取和遞迴排序時子區間端點的選擇,可以簡記為

關鍵點選左端點,子區間端點要看右指標

關鍵點選右端點,子區間端點要看左指標

關鍵點選中間,子區間端點隨意選

原因可以理解為處理特殊情況(特例見**)

在分子區間端點時,為什麼是\([l, j], [j + 1, r]\) 和 \([l, i - 1], [i, r]\)

首先要明確我們的目標是保證關鍵點左側都是 <= 它的數,關鍵點右側都是 >= 它的數。

我們看j點,最終指向的應該是 <= 關鍵點的資料,由於無法區分是小於還是等於,所以直接分到左半邊,所以是\([l, j]\),自然就對應了\([j + 1, r]\)

同理可得\(i\)這種劃分方法的原因

#include #include using namespace std;

const int n = 1e6 + 10;

int n;

int a[n];

void quick_sort(int a, int l, int r)

// 測試x的選取的資料可以是:

// 2

// 1 2

// x = a[l]; || x = a[l + r >> 1];

quick_sort(a, l, j);

quick_sort(a, j + 1, r);

// x = a[r]; || x = a[l + r >> 1];

// quick_sort(a, l, i - 1);

// quick_sort(a, i, r);

}int main()

該演算法能夠在\(o(n)\)的時間複雜度內找到無序序列中第\(k\)小的數

給定乙個長度為\(n\)的整數數列,以及乙個整數\(k\),請用快速選擇演算法求出數列從小到大排序後的第\(k\)個數

已知乙個無序序列,我們選定\(x\)作為分界值,快速排序第一輪之後,序列被分為兩半部分,左半邊所有數值\(<=x\),設長度為\(sl\);右半邊所有數值\(>=x\),設長度為\(sr\)

假設我們想要找得是第\(k\)小的數,如果\(k<=sl\),說明待求值位於左半邊,如果\(k>sl\),說明待求值位於右半邊。根據該性質,我們只需要遞迴對應區間進行快速排序,最終即可找到第\(k\)小的數

第1輪快速排序運算次數為\(n\),之後每次快排的期望運算次數依次減半,所以\(時間複雜度 = n + \frac + \frac + \ ... \ = \ n(1 + \frac + \frac + \ ...) <= 2n\),所以時間複雜度為\(o(n)\)

#include #include using namespace std;

const int n = 100010;

int n, k;

int a[n];

int quick_sort(int a, int l, int r, int k)

int sl = j - l + 1;

if (k <= sl) return quick_sort(a, l, j, k);

return quick_sort(a, j + 1, r, k - sl);

}int main()

在algorithm標頭檔案中存在乙個nth_element的函式,同樣能夠找到第k個元素

#include #include using namespace std;

const int n = 100010;

int n, k;

int a[n];

int main()

排序 快速排序模板

以某個記錄 元素 為界 該記錄稱為支點或樞軸 將待排序列分成兩部分 一部分 所有記錄的關鍵字大於等於支點記錄的關鍵字 另一部分 所有記錄的關鍵字小於支點記錄的關鍵字 演算法描述 1 任取待排序記錄序列中的某個記錄 例如取第乙個記錄 作為基準 樞 按照該記錄的關鍵字大小,將整個記錄序列劃分為左右兩個子...

快速排序 模板

說明 經過本函式處理後,陣列itemarray中元素滿足prulefunc itemarray itemr itemarray iteml 為true,其中itemr iteml template t void quicksort itemarray,int iteml,int itemr,bool...

模板 快速排序

排序演算法可以說是從語言步入演算法的第一道坎了,其中最有代表性的莫過於快排。這裡模擬庫函式自帶sort的呼叫方式,寫起來相當自然清爽。樸素快速排序演算法的複雜度最好為o nlogn 最壞時能達到o n include include include include include include d...