題目:如何得到一個數據流中的中位數?如果從數據流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從數據流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。我們使用Insert()方法讀取數據流,使用GetMedian()方法獲取當前讀取數據的中位數。
分析:使用優先級隊列將數據構建大堆(左邊),小堆(右邊),並且大堆中的所有數據都要小於小堆中的數據,並且兩個堆中的數據一樣,支撐這個過程的方法是奇數個數據時先入右邊,然後將右邊的top()入到左邊,當數據時偶數個時,先入左邊,再將左邊的top()入到右邊,這樣既保證了右邊的所有數據都大於左邊的,又保證了數據平分左右兩邊,還保證了左邊是大堆,右邊是小堆。這樣取中位數時,當此時數據有奇數個時,取左邊的堆頂(因爲第一次起始是先入到左邊的),當數據個數是偶數時,就取兩個堆頂的平均數。
//數據成員
priority_queue<int, vector<int>, less<int>> left;//左邊的大堆
priority_queue<int, vector<int>, greater<int>> right;//右邊的小堆
int count=0;//數據的個數
void Insert(int num)
{
count++;
if(count%2==0)//偶數個數據
{
left.push(num);
right.push(left.top());
left.pop();
}
else//奇數個數據
{
right.push(num);
left.push(right.top());
right.pop();
}
}
double GetMedian()
{
if((count&1)==1)//奇數個
{
return left.top();
}
else
{
return (left.top()+right.top())/2.0;
}
}