海量資料取中位數,比較簡單耗時的是用堆排序

2021-06-10 05:25:28 字數 1067 閱讀 8293

分類: 演算法

2012-05-11 20:35

68人閱讀收藏 

舉報**:

若有很大一組資料,資料的個數是n(每個數占4個位元組),記憶體大小為m個位元組,其中m<4*n,使得不能在現有記憶體情況下通過直接排序找到這n個數的中位數。解決海量資料中取中位數的方法有兩種比較簡單耗時的是用堆排序,還有一種是改造後基於段的計數:

1)分區間堆排序:

在現有m大小記憶體情況下若最多能夠造出包含p個資料的堆,則先掃瞄一次這n個資料找到最小的p個數,耗時o(nlog(p)),設這p個數中最大的數是a,將堆清空,在第二輪掃瞄出比a大的中最小的p個數,然後在把a改為記錄這p個數中最大的數,依次類推,直到計算到某一輪p個數和之前夠造出的數的個數大於n/2,在這p個數中找到所有數中的中位數,耗時的地方是每輪掃瞄構建堆都要用了o(nlog(p)),構造的次數為n/(2*p),所以它的時間複雜度是o(n*n*log(p)/(2*p)).

2)基於段的計數

基於段的計數指的的是對乙個區間範圍的計數,與計數排序不同的是後者對每乙個數出現次數的計數,而前者是對出現在某一區間範圍內的數計數,段的大小取決於記憶體大小和每段計數器所佔的位元組數,而計數器大小又受總資料量有關,需滿足計數器的最大計數能夠大於最大個數n,比如本題中記憶體大小是m個位元組,而n的大小至少需要用logn位來表示,設k個位元組表示的無符號整數可以最大值大於n,則放在記憶體中計數器個數是m/k,設q=m/k,即這n個數分為q個段,每一段的大小是n=n/q,第一段數的範圍是0~n-1,第二段是n~2*n-1,依此類推。現在我們可以從硬碟中逐個掃面這n個數,根據每個數的大小來修改他們對應範圍的計數器,需要用o(n)時間完成對這q個段的計數。然後從第一段開始往後掃瞄累加每個段的計數器,直到累加到某一段的計數器使得它和這之前的個數大於n/2,假設這個段所表示的範圍是q~q+n-1,那麼這n個數的中位數就在q~q+n-1這個範圍內,現在更改計數器的屬性不在基於段而是基於每個數,且只針對q~q+n-1這n個數計數,還需要一輪掃面n個數來完成對n個計數器的確定,在本段之前的段計數器計數之和是t,t<2/n,那麼只要依次從新的n個計數器開始累加到s,使得滿足t+s>n/2那乙個計數器,它所代表的數就是這n個數的中位數。

分享到:

海量資料找中位數

題目如下 只有2g記憶體的pc機,在乙個存有10g個整數的檔案,從中找到中位數,寫乙個演算法。給出了四種方法來解決 演算法 1.利用外排序的方法,進行排序 然後再去找中位數 2.另外還有個思路利用堆 先求第1g大,然後利用該元素求第2g大,然後利用第2g大,求第3g大.當然這樣的話雖不需排序,但是磁...

海量資料求中位數

參考 1.最簡單 排序 2.堆 4g資料,1g記憶體 步驟 先將1g記憶體都塞進乙個大頂堆,然後小於堆頂的數,插入堆,並pop堆頂,一次遍歷後,得到第1g大的數 第二次遍歷,過濾小於第1g大的數,同樣塞滿乙個1g的大頂堆,小於堆頂的插入堆,並pop堆頂,得到第2g大的數字 3.二分 統計 比如數字範...

從海量資料中找出中位數

題目 在乙個檔案中有 10g 個整數,亂序排列,要求找出中位數。記憶體限制為 2g。只寫出思路即可 記憶體限制為 2g的意思就是,可以使用2g的空間來執行程式,而不考慮這台機器上的其他軟體的占用記憶體 關於中位數 資料排序後,位置在最中間的數值。即將資料分成兩部分,一部分大於該數值,一部分小於該數值...