1. 程式人生 > >線性查找算法(BFPRT)

線性查找算法(BFPRT)

排序。 round 情況 -c fff 至少 selection 線性時間 分時

BFPRT算法的作者是5位真正的大牛(Blum 、 Floyd 、 Pratt 、 Rivest 、 Tarjan)。

BFPRT解決的問題十分經典,即從某n個元素的序列中選出第k大(第k小)的元素,通過巧妙的分析,BFPRT可以保證在最壞情況下仍為線性時間復雜度。

步驟

  1. 將n個元素每 5 個一組,分成n/5(上界)組。
  2. 取出每一組的中位數,任意排序方法,比如插入排序。
  3. 遞歸的調用 selection 算法查找上一步中所有中位數的中位數,設為x,偶數個中位數的情況下設定為選取中間小的一個。
  4. 用x來分割數組,設小於等於x的個數為k,大於x的個數即為n-k。
  5. 若i==k,返回x;若i<k,在小於x的元素中遞歸查找第i小的元素;若i>k,在大於x的元素中遞歸查找第i-k 小的元素。

 終止條件:n=1 時,返回的即是i小元素

================================
待查找的數組 : 
4 1 2 56 24 5 6 97 8 0 4 8 6 2 3 6 1 9 3 4 6 2 
找出第 8 小的數
被分割的數組 : 
4 1 2 56 24 
該數組的中位數 : 4
被分割的數組 : 
5 6 97 8 0 
該數組的中位數 : 6
被分割的數組 : 
4 8 6 2 3 
該數組的中位數 : 4
被分割的數組 : 
6 1 9 3 4 
該數組的中位數 : 4
中位數的集合 : 
4 6 4 4 
經過選擇排序後的中位數數組 : 
4 4 4 6 
定義的 x 為 : 4
================================
待查找的數組 : 
4 1 2 0 4 2 3 1 3 4 2 
找出第 8 小的數   //數組長度比8大
被分割的數組 : 
4 1 2 0 4 
該數組的中位數 : 2
被分割的數組 : 
2 3 1 3 4 
該數組的中位數 : 3
中位數的集合 : 
2 3 
經過選擇排序後的中位數數組 : 
2 3 
定義的 x 為 : 2  //前6小的數據已得出(0 1 1 2 2 2)
================================
待查找的數組 : 
4 4 3 3 4 
找出第 2 小的數   3 //(8-6=2  查出第二2小的數據)
第 8 小的數為 : 3
(0 1 1 2 2 2 3 3 4 4 4 5 6 6 6 6 8 8 9 24 56 97)

ps:

1.為何利用5作為元組大小,可能是與寄存器的數量和運算有關。

2.為何稱為線性的解答:

劃分時以5個元素為一組求取中位數,共得到n/5個中位數,再遞歸求取中位數,復雜度為T(n/5)。

得到的中位數x作為主元進行劃分,在n/5個中位數中,主元x大於其中1/2*n/5=n/10的中位數,而每個中位數在其本來的5個數的小組中又大於或等於其中的3個數,所以主元x至少大於所有數中的n/10*3=3/10*n個。同理,主元x至少小於所有數中的3/10*n個。即劃分之後,任意一邊的長度至少為3/10,在最壞情況下,每次選擇都選到了7/10的那一部分,則遞歸的復雜度為T(7/10*n)。

在每5個數求中位數和劃分的函數中,進行若幹個次線性的掃描,其時間復雜度為c*n,其中c為常數。

其總的時間復雜度滿足: T(n)<=T(n/5)+T(7/10*n)+c*n

假設T(n)=x*n,其中x不一定是常數(比如x可以為n的倍數,則對應的T(n)=O(n^2))。則有 x*n <= x*n/5 + x*7/10*n + c*n。得到 x<=10*c

於是可以知道x與n無關,T(n)<=10*c*n,為線性時間復雜度算法。

而這又是最壞情況下的分析,故BFPRT可以在最壞情況下以線性時間求得n個數中的第k個數。

線性查找算法(BFPRT)