數據流中的中位數

 

題目:如何得到一個數據流中的中位數?如果從數據流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從數據流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。我們使用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;
        }
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章