zoukankan      html  css  js  c++  java
  • 《剑指offer》第四十一题(数据流中的中位数)

    // 面试题41:数据流中的中位数
    // 题目:如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么
    // 中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,
    // 那么中位数就是所有数值排序之后中间两个数的平均值。
    
    #include <iostream>
    #include <algorithm>
    #include <vector>
    
    
    using namespace std;
    
    template<typename T> class DynamicArray
    {
    public:
        void Insert(T num)
        {
            if (((min.size() + max.size()) & 1) == 0)//没插入前判断当前总个数是奇还是偶,偶时插入最小堆
            {
                if (max.size() > 0 && num < max[0])//若该值属于最大堆
                {
                    max.push_back(num);//则先插入最大堆
                    push_heap(max.begin(), max.end(), less<T>());//使最后一个元素插到合适位置,符合最大堆规则
    
                    num = max[0];//令num等于最大堆里的最大值
    
                    pop_heap(max.begin(), max.end(), less<T>());//交换最大堆的最大值和最后一个值,弹出最大值,符合最大堆规则
                    max.pop_back();//删除最后一个元素,即刚才所述的最大值
                }
    
                min.push_back(num);//将num插入最小堆
                push_heap(min.begin(), min.end(), greater<T>());//使最后一个元素插到合适位置,符合最小堆规则
            }
            else//奇数插入最大堆,使大小堆保持平衡,下面代码同上
            {
                if (min.size() > 0 && min[0] < num)
                {
                    min.push_back(num);
                    push_heap(min.begin(), min.end(), greater<T>());
    
                    num = min[0];
    
                    pop_heap(min.begin(), min.end(), greater<T>());
                    min.pop_back();
                }
    
                max.push_back(num);
                push_heap(max.begin(), max.end(), less<T>());
            }
        }
    
        T GetMedian()
        {
            int size = min.size() + max.size();
            if (size == 0)
                throw exception("No numbers are available");
    
            T median = 0;
            if ((size & 1) == 1)
                median = min[0];//若总个数是奇数,则中值是最小堆的顶点
            else
                median = (min[0] + max[0]) / 2;//否则是最大堆和最小堆的顶点平均值
    
            return median;
        }
    
    private:
        vector<T> min;
        vector<T> max;
    };
    
    // ====================测试代码====================
    void Test(const char* testName, DynamicArray<double>& numbers, double expected)
    {
        if (testName != nullptr)
            printf("%s begins: ", testName);
    
        if (abs(numbers.GetMedian() - expected) < 0.0000001)
            printf("Passed.
    ");
        else
            printf("FAILED.
    ");
    }
    
    int main()
    {
        DynamicArray<double> numbers;
    
        printf("Test1 begins: ");
        try
        {
            numbers.GetMedian();
            printf("FAILED.
    ");
        }
        catch (const exception&)
        {
            printf("Passed.
    ");
        }
    
        numbers.Insert(5);
        Test("Test2", numbers, 5);
    
        numbers.Insert(2);
        Test("Test3", numbers, 3.5);
    
        numbers.Insert(3);
        Test("Test4", numbers, 3);
    
        numbers.Insert(4);
        Test("Test6", numbers, 3.5);
    
        numbers.Insert(1);
        Test("Test5", numbers, 3);
    
        numbers.Insert(6);
        Test("Test7", numbers, 3.5);
    
        numbers.Insert(7);
        Test("Test8", numbers, 4);
    
        numbers.Insert(0);
        Test("Test9", numbers, 3.5);
    
        numbers.Insert(8);
        Test("Test10", numbers, 4);
        system("pause");
        return 0;
    }
  • 相关阅读:
    手动执行把nconf生成的配置文件附加到nagios下
    创建django工程
    mysql安装、配置、导入数据库
    PHP里<?php和<?通用要在配置里怎么设置_百度知道
    Loganalyzer数据库乱码解决方法:
    RSyslog安装配置
    修改cacti的系统时间
    Mysql5.7.11 安装 cacti0.8.8f ,在导入cacti.sql数据库时出现下记错误,导致数据库导入终止: ERROR 1067 (42000) at line 1847: Invalid default value for 'status_fail_date'
    中间件组件
    cookie与session 组件
  • 原文地址:https://www.cnblogs.com/CJT-blog/p/10520259.html
Copyright © 2011-2022 走看看