BFPRT演算法O n 解決第k小的數

2022-04-17 12:21:13 字數 2114 閱讀 4092

第k小演算法

我們通常會簡單地進行乙個快速排序後,得到第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小的。

#include #include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define inf 0x3f3f3f3f

#define ll long long

#define maxn 1000010

using

namespace

std;

const

int n = 1000005

;int

a[n];

int findmedian(int a , int l , int

r)

if(i<=r)

if(index == 1) return

a[l];

else

return findmedian(a , l , l+index-1);}

//以p位置上的數字作為基準點劃分,返回的i是最後基準點所在的位置

int partion(int a , int l , int r , int

p) a[i] =pivot;

returni;}

//在a陣列的[l,r]區間內找到第k小的數字,k從1開始

int findkthmin(int a , int l , int r , int

k)int

main()

return0;

}

其實bfprt的partion部分和快排的patition方法是差不多的。只是基準點的選取不一樣罷了

演算法題 BFPRT演算法 求第K小或者第K大的數

2017 11 21 bfprt問題 乙個陣列中求第k小或者第k大的數 不通過排序求第k小的數,時間複雜度為o n 1 找到乙個劃分值,按照partition的過程,分為小於區 等於區 大於區,則可知等於區是在整個陣列有序後不變的部分。2 求第k小的數,就是陣列有序後下標為k 1的數。3 所以,如果...

第k個小的數 bfprt演算法與快排改進

public static intfindk int nums,int m,int n int k while i temp if i nums m nums j nums j temp if j 1 k else if j 1 k else public static void main stri...

分治演算法求第k小元素

1.問題 用分治的演算法求乙個陣列s n 中第k小的元素。2.解析 採取和快速演算法相同的思路,但是結合分治的思想,選取恰當的基準值。找到基準值以後,再按照快速排序的方法進行查詢就好了。3.設計 int r 5int r group ceil high low 1 1.0 r ceil取上限,總共分...