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...