基於快速排序的O(N)時間複雜度的TopK演算法原理

2021-09-19 03:35:53 字數 1376 閱讀 1320

實際應用中,我們經常面臨這樣的問題,即從乙個序列s中選擇其中最大的k個數(一般情況下k遠小於|s|),我們將這種問題稱為topk問題。

諸如此類的應用場景很多,本文借助快速排序的思想,給出解決此問題的乙個時間複雜度為o(n)的演算法。

為了引出本文基於快排topk的思想,先給出快排的演算法描述,令s為待排序集合,|s|表示集合元素數量。

1、如果 s 中元素個數是0或1,則返回。

2、取 s 中任一元素 v, 稱之為樞紐元。

3、將 s - (s中其餘元素) 分成兩個不相交的集合:

4、返回 。

本人部落格中的**便是該思想的實現,可供參考。

其實,只要稍加修改快排演算法,即可實現平均時間複雜度為o(n)的topk演算法,我們稱之為quickselect(s, k)。

1、如果|s| = 1,返回s,否則若|s| < 20,則使用選擇排序對s排序,選擇最大的k個元素返回

2、選取乙個樞紐元 v 屬於 s。(同快速排序步驟2

3、將集合 s - 分割成 s1 和 s2。 (同快速排序步驟3

4、如果k <= |s1| ,則k個元素必然全部位於集合s1中,並返回quickselect(s1, k);如果k = |s1| + 1,則集合s1 與 樞紐元 v 恰好是所求的k個數,我們將 s1 和 v 一併返回;如果k > |s1| + 1,那麼s1和樞紐元v必然是k個元素的一部分,剩餘k - |s1| - 1 個元素必然存在集合 s2 中,因此我們應該返回 s1 + v + quickselect(s2, k - |s1| - 1)。

仔細分析該演算法可得如下結論:

結論2易於理解。分析演算法可知,每一輪遞迴開始之前,我們已經消去了1個集合,遞迴僅作用在另外乙個集合,結論2於是成立。結論3的推導依賴結論1。

在理想情況下,樞紐元 v 的選擇使每輪遞迴都近似的將當前集合等分,故最多需要遞迴o(logn)次:

第1次遞迴對應的集合長度為 |s / 2|,

第2次遞迴對應的集合長度為 |s / 4|,

第3次遞迴對應的集合長度為 |s / 8|,

第log(n) 次遞迴對應的集合長度為 1,

將o(logn)次遞迴的集合長度相加,

sum = |s / 2| + |s / 4| + |s / 8| + ...... + 1

這是等比數列,根據等比數列求和方法可得sum大約等於2n,故快速選擇的平均時間複雜度為o(n)。

快速排序的時間複雜度與空間複雜度

我理解的是,快速排序用的是分治法,運用的遞迴的演算法,先挑選乙個基準值,小於基準值的數放在左邊,大於基準值的數放在基準值的右邊,這樣就涇渭分明的三塊 但是這三塊是有序的,基準值左邊右邊的內 部數是無序的,所以,將基準值左右兩端繼續進行快速排序,直到區間長度為1,排序就完成了。下面使用vs2013實現...

基於比較的快速排序 時間複雜度為O nlogn

快速排序 快排利用的是分治思想。如果要排序陣列中下標從 p 到 r 之間的一組資料,選擇p 到 r 之間的任意乙個資料作為分割槽點pivot。遍歷 p 到 r 之間的資料,將小於pivot的放到左邊,將大於pivot的放到右邊,將pivot放到中間。經過這一步驟後陣列 p 到 r 之間的資料就被分為...

快速排序時間複雜度分析

為了分析快速排序的時間複雜度,請先看下面的主定理 主定理 t n at n b f n 其中 a 1 and b 1 是常量 並且 f n 是乙個漸近正函式,為了使用這個主定理,您需要考慮下列三種情況 快速排序的每一次劃分把乙個 問題分解成兩個子問題,其中的關係可以用下式表示 t n 2t n 2 ...