資料結構與演算法之BFPRT演算法

2021-09-25 01:27:06 字數 4038 閱讀 4563

bfprt演算法介紹

bfprt演算法**實現

引用自部落格:bfprt演算法o(n)解決第k小的數:

在一大堆數中求其前k大或前k小的問題,簡稱top-k問題。而目前解決top-k問題最有效的演算法即是bfprt演算法,其又稱為中位數的中位數演算法,該演算法由blum、floyd、pratt、rivest、tarjan提出,最壞時間複雜度為o(n)。

我們通常會簡單地進行乙個快速排序後,得到第k個位置上的數字即可。

我們都知道的是快速排序是個不穩定的排序,它的排序過程簡單的理解主要是兩個概念partion,pivot(基準數)

一趟快速排序的過程如下:

先從序列中選取乙個數作為基準數

將比這個數大的數全部放到它的右邊,把小於或者等於它的數全部放到它的左邊

一趟快速排序也叫做partion,即將序列劃分為兩部分,一部分比基準數小,另一部分比基準數大,然後再進行分治過程,因為每一次partion不一定都能保證劃分得很均勻,所以最壞情況下的時間複雜度不能保證總是o(nlogn)的。

bfprt演算法

在bfptr演算法中,僅僅是改變了快速排序partion中的pivot值的選取,在快速排序中,我們始終選擇第乙個元素或者最後乙個元素作為pivot,而在bfptr演算法中,每次選擇五分中位數的中位數作為pivot,這樣做的目的就是使得劃分比較合理,從而避免了最壞情況的發生。

演算法步驟如下

(1)將輸入陣列的n個元素劃分為n/5組,每組5個元素,且至多只有乙個組由剩下的n%5個元素組成。

(2)尋找n/5個組中每乙個組的中位數,首先對每組的元素進行插入排序,然後從排序過的序列中選出中位數。

(3)對於(2)中找出的n/5個中位數,遞迴進行步驟(1)和(2),直到只剩下乙個數即為這n/5個元素的中位數,找到中位數後並找到對應的下標p。

(4)進行partion劃分過程,partion劃分中的pivot元素下標為p。

(5)進行高低區判斷即可。

本演算法的最壞時間複雜度為o(n),值得注意的是通過bfptr演算法將陣列按第k小(大)的元素劃分為兩部分,而

這高低兩部分不一定是有序的,通常我們也不需要求出順序,而只需要求出前k大的或者前k小的。

附上堆排序下找k小的值和bfprt演算法的**實現

public

class

code_06_bfprt

int[

] kheap =

newint

[k];

for(

int i =

0; i != k; i++

)for

(int i = k; i != arr.length; i++)}

return kheap;

}public

static

void

heapinsert

(int

arr,

int value,

int index)

else}}

public

static

void

heapify

(int

arr,

int index,

int heapsize)

if(right < heapsize && arr[right]

> arr[largest])if

(largest != index)

else

index = largest;

left = index *2+

1;right = index *2+

2;}}

// o(n)

public

static

int[

]getminknumsbybfprt

(int

arr,

int k)

int minkth =

getminkthbybfprt

(arr, k)

;int

res =

newint

[k];

int index =0;

for(

int i =

0; i != arr.length; i++)}

for(

; index != res.length; index++

)return res;

}public

static

intgetminkthbybfprt

(int

arr,

int k)

public

static

int[

]copyarray

(int

arr)

return res;

}public

static

intselect

(int

arr,

int begin,

int end,

int i)

int pivot =

medianofmedians

(arr, begin, end)

;int

pivotrange =

partition

(arr, begin, end, pivot);if

(i >= pivotrange[0]

&& i <= pivotrange[1]

)else

if(i < pivotrange[0]

)else

}public

static

intmedianofmedians

(int

arr,

int begin,

int end)

return

select

(marr,

0, marr.length -

1, marr.length /2)

;}public

static

int[

]partition

(int

arr,

int begin,

int end,

int pivotvalue)

else

if(arr[cur]

> pivotvalue)

else

}int

range =

newint[2

];range[0]

= small +1;

range[1]

= big -1;

return range;

}public

static

intgetmedian

(int

arr,

int begin,

int end)

public

static

void

insertionsort

(int

arr,

int begin,

int end)

else}}

}public

static

void

swap

(int

arr,

int index1,

int index2)

public

static

void

printarray

(int

arr)

system.out.

println()

;}public

static

void

main

(string[

] args)

;// sorted :

printarray

(getminknumsbyheap

(arr,10)

);printarray

(getminknumsbybfprt

(arr,10)

);}}

資料結構與演算法之演算法

1.乙個問題的解可以分解為幾個子問題的解 2.這個問題與分解之後的子問題,除了資料規模不同,求解思路完全一樣 3.存在遞迴終止條件 假如這裡有 n 個台階,每次你可以跨 1 個台階或者 2 個台階,請問走這 n 個台階有多少種 走法?如果有 7 個台階,你可以 2,2,2,1 這樣子上去,也可以 1...

資料結構與演算法 演算法 演算法和資料結構

資料結構與演算法 演算法 好吧,在這裡,您被優秀或優秀的軟體開發人員所隔開。在這種情況下,我會告訴您一開始或至少在我的情況下,並且我知道大多數時候,對於我認識的大多數人,您會覺得自己是乙個無能的人或白痴。基本上,我怎麼可能不理解這一點,然後您會感到沮喪。在這種情況下,我會告訴您情況並不像您想的那麼糟...

《資料結構與演算法》之資料結構簡介

資料結構 資料 結構,資料結構是計算機儲存 組織資料的方式。資料結構是指相互之間存在一種或多種特定關係的資料元素的集合。通常情況下,精心選擇的資料結構可以帶來更高的執行或者儲存效率。資料結構往往同高效的檢索演算法和索引技術有關。一 資料的邏輯結構 指反映資料元素之間的邏輯關係的資料結構,其中的邏輯關...