题目描述:
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
分析:
完整代码:
class Solution {
public:
void Insert(int num)
{
//如果数据流中读出的个数是偶数
if((max.size() + min.size() & 1) == 0)
{
//如果 max 堆中存在元素且 num 小于 max 中的第一个元素
if(max.size() > 0 && num < max[0])
{
//将元素压入到 max堆中
max.push_back(num);
//以 less 重新排序
push_heap(max.begin(), max.end(), less<int>());
//记录 max 中最大的元素
num = max[0];
//将 max[0] 移到 max 的尾部,以 less的方式重新排序
pop_heap(max.begin(), max.end(), less<int>());
//将 max 尾部的元素弹出
max.pop_back();
}
//将 num 压入到 min 堆中
min.push_back(num);
//以 greater 重新排序
push_heap(min.begin(), min.end(), greater<int>());
}
//如果数据流中读出来的是奇数
else
{
//如果 min 堆中存在元素且 num 大于 min堆中的第一个元素
if(min.size() > 0 && num > min[0])
{
//将 num 压入到 min堆中
min.push_back(num);
//以 greater 的方式重新排序
push_heap(min.begin(), min.end(), greater<int>());
//记录 min 堆中最小的元素
num = min[0];
//将 min 堆中第一个元素移到堆的尾部
pop_heap(min.begin(), min.end(), greater<int>());
//将 min 堆中尾部的元素弹出
min.pop_back();
}
//将 num 压入到 max堆中
max.push_back(num);
//以 less 的方式重新排序
push_heap(max.begin(), max.end(), less<int>());
}
}
double GetMedian()
{
//声明一个变量,表示中位数
double Median;
//声明一个变量,表示从数据流中读取到的元素个数
int value = 0;
value = min.size() + max.size();
//如果读取的元素个数为0
if(value == 0)
return 0.0;
//如果读到的元素个数是偶数
if((value & 1) == 0)
{
Median = (min[0] + max[0]) / 2.0;
}
// 如果读取到的元素是奇数
else
Median = min[0];
//返回寻找到的中位数
return Median;
}
private:
//声明一个最小堆
vector<int> min;
//声明一个最大对;
vector<int> max;
};
相关知识点:
1、C++ 模板详解;
注意:模板的声明或定义只能在全局,命名空间或类范围内进行。即不能在局部范围,函数内进行,比如不能在main函数中声明或定义一个模板。
参考资料:https://www.cnblogs.com/gw811/archive/2012/10/25/2738929.html
2、C++ 类的定义;
参考资料: https://www.cnblogs.com/mr-wid/archive/2013/02/18/2916309.html
3、make_heap()、pop_heap()、push_heap()用法;
参考链接:https://blog.csdn.net/liu_sheng_1991/article/details/52298887
https://blog.csdn.net/whistlena/article/details/52032067
4、&& 、 & 的区别;
(1)、&&:逻辑与是对boolean值得操作,属于离散学范畴,是条件计算操作,用来判断真假的;
(2)、&:按位与是对计算机位的操作,属于计算机的二进制范畴,进行的是位操作,用来计算的。