資料流中的中位數

2021-08-17 07:07:19 字數 1719 閱讀 3480

1、題目描述

如何得到乙個資料流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。

2、**

2.1 原理:用兩個堆實現,左邊是做大堆,右邊是最小堆,當資料總數是偶數的時候,中位數是兩個堆首元素和的一半;當資料是奇數的時候,可以約定取最大堆或者是最小堆的首元素。

2.2 思路:中位數是一串資料中大小排在正中間的數,那麼排到中位數左邊的數都比中位數小,右邊的比中位數大,因此,只需要實時將當前資料分為兩堆,左邊一堆的最大值比右邊最小堆的最小值要小,中位數就有左邊堆的最大和右邊堆的最小決定。這樣,求中位數只需要實時記錄左右兩堆資料的最大和最小值即可,那麼用最大最小堆即可實現。

最大最小堆需要滿足的條件:

(1)最大最小堆任何時候元素個數之差不能大於1

(2)左邊最大堆的元素最大元素不能大於右邊最小堆的最小元素,以保證資料的有序性。

2.3 **:

#include

#include

#include

#include

using

namespace

std;

class solution

//再向最小堆新增元素

minheap.push_back(num);

push_heap(minheap.begin(), minheap.end(), greater()); //最小堆

}//之前是奇數個數,將當前元素插入到最大堆

else

//再向最大堆插入元素

maxheap.push_back(num);

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

double getmedian()

else

return minheap[0];

}};

注意:

(1)當當前總的資料個數是偶數的時候,直接取最大堆和最小堆的首元素的均值就是最後的中位數。如果是奇數,那麼就與之前約定的插入的時候的順序有關,這點需要對應起來。

(2)當乙個資料按照當前資料個數的奇偶性應該插入到最大堆的時候,如果當前數值大於最小堆的最小值,如果將該數直接插入最大堆,上述條件2不滿足,解決辦法是現將該數插入最小堆,再將最小堆的最大值彈出並插入到最大堆;同理,當乙個應該插入最小堆,但是其值小於最大堆的最大值的時候,處理思路一樣。

3.1 back系列和heap系列的區別:

back系列是操作容器元素新增和刪除的方法,heap是堆排序的方法。不要混淆。

3.2 pop_back vs push_back

pop_back將乙個容器的最後乙個元素刪除,push_back是往容器最後新增乙個元素。 兩者一般都沒有返回值。

3.3 push_heap/pop_heap的區別

(1)push_heap是在容器新增乙個元素後,將其堆排序,less()對應最大堆排序,greater()對應最小堆排序。less和greater定義在標頭檔案中。該方法一般用在向容器最後新增了元素之後。

(2)pop_heap是將當前容器的第一元素移到最後,並將剩餘的元素堆排序。less()對應最大堆排序,greater()對應最小堆排序,同之前。

關於更多這方面的講解見部落格:

資料流中的中位數

資料流中的中位數 如何得到乙個資料流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。解題思路 維護乙個大堆和乙個小堆,大堆表示序列前一半數,小堆表示序列後一半數,保持兩個堆的元素個...

資料流中的中位數

如何得到乙個資料流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。class solution double getmedian else private vectordata c...

資料流中的中位數

如何得到乙個資料流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。簡單題 找中位數 coding utf 8 class solution x def insert self,nu...