找出序列中的中位數

2021-07-05 02:41:44 字數 1270 閱讀 7304

乙個隨機序列,找出序列的中位數,當序列個數為奇數時,為中間位置上的數字;當序列為偶數時,為中間兩個數字的平均值。

這種題有很多種做法,比較有代表性的由:

1、partition法

利用快排關鍵字的查詢方法

a.隨機選取乙個關鍵字key,將序列二分;

b.若關鍵字的下標大於n/2,則繼續對序列的左半部分執行partition;

c.若關鍵字的下標小於n/2,則繼續對序列的左半部分執行partition;

d.若關鍵字的下標等於n/2,則返回key。

這種演算法:partition的時間複雜度為o(n),獲取中位數的時間複雜度為o(1)。

2、利用平衡二叉查詢樹

沒讀取乙個數字,將數字插入到二叉樹中,並調整二叉樹的平衡性。最後根節點就是想要的中位數。

構建平衡二叉查詢樹的演算法時間複雜度為o(logn),取出中位數的時間複雜度為o(n)。但是調整平衡二叉查詢樹演算法實現比較複雜。

3.利用堆

原理分析:中位數無非就是將序列分為兩個部分,左邊的部分都小於中位數,右邊的序列都大於中位數。這比較符合堆的特性(看看資料結構在演算法中的重要性,選擇好的資料結構能夠讓演算法事半功倍)。可以將序列分成兩個部分,左邊的部分夠著大根堆,右邊的部分構造小根堆。

具體實現細節:

a.如果堆中元素的個數為偶數時,將新數字插入小根堆中(插入後堆元素的個數為奇數,此時結束插入,返回小根堆堆頂元素);如果堆中的元素個數為奇數時,將新數字插入大根堆中(插入後堆元素的個數為偶數,此時結束插入,返回兩堆堆頂元素的均值)。

b.若插入小根堆的元素大於大根堆堆頂的元素,說明新元素位於序列的右半部分,應當插入大根堆。而此時大根堆堆頂元素應當位於左半序列(小頂堆)中,因此需要將大根堆堆頂元素插入小根堆。若插入若插入小頂堆的元素不大於大頂堆堆頂的元素,則直接插入小根堆。

c.同理,向大根堆插入元素時也有如上考慮。

調整堆的時間複雜度為o(logn),取中位數的時間複雜度為o(1)。

演算法實現:

template

class solution

maxheap.push_back(num);

push_heap(maxheap.begin(),maxheap.end(),less());

}else

minheap.push_back(num);

push_heap(minheap.begin(),minheap.end(),greater());}}

t getmedian()

};

從海量資料中找出中位數

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

從海量資料中找出中位數

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

中位數的中位數

參照王曉東的演算法設計 中位數的中位數,即將一串數分成n段,求其排好序了的中間那個數,再把這些所有中位數再求一次中位數。for int i 0 i r p 4 5 i 找中位數的中位數,r p 4即上面所說的n 5 int x lineselect a,p,p r p 4 5,r p 4 10 線性...