BFPRT(中位數的中位數)演算法

2021-08-09 03:08:25 字數 1632 閱讀 8943

又稱為 「中位數的中位數演算法」,該演算法由 blum、floyd、pratt、rivest、tarjan 在2023年提出,最壞時間複雜度為o(n),最差的空間複雜度為o(logn)

演算法步驟

(1):將 n 個元素劃分為 ⌊n/5⌋ 個組,每組 5 個元素,若有剩餘,捨去;

(2):使用排序方法找到 ⌊n/5⌋ 個組中每一組的中位數;

(3):對於(2)中找到的所有中位數,遞迴(1)(2)查詢中位數的中位數,作為partition劃分過程的主元

(4):進行partition劃分,即一次快排

(5):判斷主元的位置與 k 的大小,有選擇的對左邊或右邊遞迴。

演算法應用

bfprt演算法的乙個經典應用就是top-k問題,即在一組資料中尋找第k大或第k小的元素。

這類問題可以分為對資料完全排序,部分排序和不排序。

完全排序情況下可以使用快速排序等排序方法能達到o(nlogn)的時間複雜度。

部分排序可以使用氣泡排序,選擇排序等方法也能達到o(kn)的時間複雜度。

不排序的情況可以使用堆排序的方法,時間複雜度為o(nlogk)

而bfprt演算法解決這類問題能達到o(n)的時間複雜度!!

實現**

#include 

#include

using

namespace

std;

intarray=;

// 插入排序,返回中位數下標

int insertsort(int left,int right)

return (left+right)>>1;

}int bfprt(int,int,int);

//返回中位數的中位數的下標

int getpivotindex(int left,int right)

return bfprt(left,back,((left+back)>>1)+1);

} //一趟快排

int partition(int left,int right,int pivotindex)

swap(array[right],array[mid]);

return mid;

}int bfprt(int left,int right,int k)else

if(count>k) else

} int main()

cout

cout

<

0;}

演算法複雜度分析中位數的遞迴呼叫不超過最壞的線性情況,因為中位數列表是整個列表大小的20%,而其他的遞迴呼叫列表的最多70%,令t(n)為時間複雜度,則

使用歸納法,可以得到

分析過程參考median of medians

BFPRT演算法(中位數之中位數)初窺 五

bfprt演算法的作者是5位真正的大牛 blum floyd pratt rivest tarjan 該演算法入選了在stackexchange上進行的當今世界十大經典演算法,而演算法的簡單和巧妙頗有我們需要借鑑學習之處。bfprt解決的問題十分經典,即從某n個元素的序列中選出第k大 第k小 的元素...

中位數的中位數

參照王曉東的演算法設計 中位數的中位數,即將一串數分成n段,求其排好序了的中間那個數,再把這些所有中位數再求一次中位數。for int i 0 i r p 4 5 i 找中位數的中位數,r p 4即上面所說的n 5 int x lineselect a,p,p r p 4 5,r p 4 10 線性...

hive 中位數 Hive的中位數

關於求解中位數,我們知道在python中直接有中位數處理函式 mean 比如在python中求解乙個中位數,很簡單。python計算中位數 import numpy as np nums 1.1,2.2,3.3,4.4,5.5,6.6 均值np.mean nums 中位數 np.median num...