BFPTR演算法(求序列中第k小的數)

2021-09-16 13:54:51 字數 1467 閱讀 8334

1973 年,blum、floyd、pratt、rivest、tarjan一起發布了一篇名為 「time bounds for selection」 的**,給出了一種在陣列中選出第k大元素平均複雜度為o(n)的演算法,俗稱」中位數之中位數演算法」。

其思想是基於對快速排序劃分過程pivot的值得優化,bfptr演算法選取每5分中位數的中位數進行劃分(中位數的中位數演算法)

過程:將序列從左到右5個5個分組,而且元素個數小於5的組至多有一組

將每組按降序排序(從大到小),選出每組的中位數,最後一組元素數若為偶數個,則選取較大的元素

對於步驟2中的中位數遞迴進行步驟1和步驟2,直到只剩下乙個數即為中心數

基於中心數對序列進行劃分(partion),進行高低區的判斷後決定是否進行遞迴

**實現:

#include #include const int n = 100;

using namespace std;

bool isbigger(int a, int b)

int find_mid(int a, int left, int right) //查詢中位數的中位數

//迴圈之後序列前排即是每組數的中位數,有(right-left)/5上取整個

int num = right - i + 1;

//num是個數小於5的組

//處理該組資料

if (num > 0)

n /= 5; //前排中位數的個數

if (n <= 1) //剩餘兩個中位數,直接返回較小的

return a[left];

else //超過兩個中位數,則繼續在中位數中尋找中位數

return find_mid(a, left, left + n);

}int find_pos(int a, int left, int right,int mid)

}int partion(int a, int left, int right,int pos) //進行劃分,類似快速排序的劃分過程

//劃分結束後,pivot前面的都是比pivot小的,pivot後面都是比pivot大的

a[i] = pivot; //確定pivot在序列中的位置

return i; //將pivot的下標返回

}int bfptr(int a, int left, int right, int k) //bfptr演算法

int main(int argc, char** ar**)

; cout << bfptr(a, 0, 9, 2);

return 0;

}結果:1

該演算法最壞情況下的時間複雜度為o(n)

C 求無序序列中第k小的元素

c 求無序序列中第k小的元素 利用優先佇列 priority queue 求出乙個無序整數列中第k小的元素 先輸入序列長度 再輸入該整數列 最後輸入第k小元素位置 k 實驗例子 5 序列長度 2 4 3 6 5 該整數列 2 第k小元素位置 3 輸出結果 如下 include include usi...

求序列第K大演算法總結

參考部落格 傳送門 在上面的部落格中介紹了求序列第k大的幾種演算法,感覺收益良多,其中最精巧的還是利用快速排序的思想o n 查詢的演算法。仔細學習以後我將其中的幾個實現了一下。解法 1 將亂序陣列從大到小進行排序然後取出前k大,總的時間複雜度為o nlogn 解法 2 利用選擇排序或互動排序,取出前...

求無需序列中第k小的元素(優先佇列)

編寫乙個實驗程式,利用priority queue 優先佇列 求粗乙個無序整數序列中第k小的元素 分析 建立乙個priority queue,greater 的小根堆pq,將陣列a中的所有元素進隊,再連續出隊,第k個出隊元素即為所求。對應 如下 include include using names...