線性時間找到第k小的元素 快排應用與BFPRT演算法

2021-10-23 09:26:48 字數 1674 閱讀 7647

面對這個問題,最簡單的想法是對資料進行排序,然後根據下標即可找到第k小的元素,目前已知的排序演算法的最低時間複雜度為o(n

log⁡

2log⁡2

n)

o(n\sqrt})

o(nlog2​

log2​n

​),但並不為人熟知。目前應用最廣的排序演算法的最低時間複雜度為o(n

log⁡2n

)o(n\log_2 n)

o(nlog2​

n)。但是,作為完美主義者的程式設計師,需要思考,找到第k小的元素一定需要排序嗎?但除了尋找最大或最小的元素之外,我們似乎只能選擇排序。那麼能否只進行部分排序,便可找到第k小的元素呢?答案是顯然的,只需要採用每一趟都能確定乙個固定元素的排序演算法即可。

思考o (n

log⁡2n

)o(n\log_2 n)

o(nlog2​

n)的排序演算法中有哪些演算法每一趟可以確定乙個固定元素,答案是快速排序和堆排序(不考慮錦標賽排序,堆排序是錦標賽排序的公升級版)。這裡以快速排序為例,方便引入後面介紹的bfprt演算法,不過還有乙個原因是堆排序獲取第k小的元素的時間複雜度是o(n

)o(n)

o(n)

的概率小於快速排序。

我們知道,快排每一趟都會有隨機有乙個元素處於最終位置上,故只需在快排中設定乙個新的遞迴出口再加以微改便能返回第k小的元素。

**如下:

這裡採用的快排為隨機化快速排序,沒有了解過的的朋友可以看一下我的另外一篇部落格:公升級版快速排序——隨機化快速排序

templatevoid partition(t array,int left,int right,int& mid)

array[i] = temp;

mid = i;

}templatet random_quick_sort(t array, int left, int right,int k)

這個演算法的時間複雜度的確定需要用到指示器隨機變數。e[t

(n)]

=e[∑

k=0n

−1xk

(t(m

ax

e[t(n)]=e[\sum_^x_k(t(max

e[t(n)

]=e[

∑k=0

n−1​

xk​(

t(max))

+θ(n

)]

))+\theta(n)]

))+θ(n

)],最終得到e[t

(n)]

=θ(n

)e[t(n)]=\theta(n)

e[t(n)

]=θ(

n),即該演算法的時間複雜度的期望值為o(n

)o(n)

o(n)

但是存在最壞情況,即每一次劃分只能劃分出乙個部分,即t(n

)=t(

n−1)

+θ(n

)t(n)=t(n-1)+\theta(n)

t(n)=t

(n−1

)+θ(

n),由等差級數可以得到最壞情況下的時間複雜度為o(n

2)

o(n^2)

o(n2

)不想寫了,困了

重寫了這篇部落格,新內容已放進去,轉到那邊去吧:找到第k小的元素【top-k】:快排應用與bfprt演算法

選擇問題 線性時間內找到序列的第k小的元素

選擇問題 在序列中按順序找到某個元素。這可以用排序方法做到,即先排個序,在找到指定元素,但是這樣就按最快的堆排序 合併排序啥的都得是o nlgn 數量級的,這裡採取的方法可以在期望為o n 的時間內完成。具體的實現方式如下 int select int a,int begin,int end,int...

快排擴充套件 第k小的數

使用快排中的partition方法,可以很快找到乙個無序序列中的第k小的數。思想 對於乙個陣列a 0.n 1 分段成a 0.st 1 a s a st 1.n 1 分組後,a 0.st 1 裡面的元素都小於等於a st a st 1.n 1 裡面的元素都大於等於a st 所以,如果 st k 1,那...

選擇第K大元素(快排 快選以及k 選取比較)

先看執行結果 按照書中所給的快排 快選以及k 選取演算法分別寫出函式檢測執行結果以及時間 發現不出所料的直接快排演算法會慢很多,但預想更穩定的k 選取演算法的耗時比預期設想要大,而相對不太穩定的快選演算法卻是三者之中最快的,為了避免偶然性,又重複做了多組實驗,並將n的範圍擴大到100 1000000...