数据流中的中位数
来源:互联网 发布:java运行jar包中的类 编辑:程序博客网 时间:2024/06/14 02:43
问题:如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有值排序之后位于中间的数值。如果数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
分析:下面总结使用了没有排序的数组、排序的数组、排序的链表、二叉搜索树、AVL数、最大堆和最小堆几种不同的数据结构的时间复杂度。
思路:综合考虑用堆实现,考虑将数据序列从中间开始分为两个部分,左边部分使用大根堆表示,右边部分使用小根堆存储。每遍历一个数据,计数器count增加1,当count是偶数时,将数据插入小根堆;当count是奇数时,将数据插入大根堆。当所有数据遍历插入完成后(时间复杂度为O(logn) ,如果count最后为偶数,则中位数为大根堆堆顶元素和小根堆堆顶元素和的一半;如果count最后为奇数,则中位数为小根堆堆顶元素。
详细的实现代码如下:
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]; pop_heap(max.begin(), max.end(), less<T>()); max.pop_back(); } min.push_back(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;};// ==================== Test Code ====================void Test(char* testName, DynamicArray<double>& numbers, double expected){ if(testName != NULL) printf("%s begins: ", testName); if(abs(numbers.GetMedian() - expected) < 0.0000001) printf("Passed.\n"); else printf("FAILED.\n");}int main(int argc, char* argv[]){ DynamicArray<double> numbers; printf("Test1 begins: "); try { numbers.GetMedian(); printf("FAILED.\n"); } catch(exception e) { printf("Passed.\n"); } 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);return 0;}
0 0
- 数据流中的中位数
- 数据流中的中位数
- 求数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- 【63】数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- Q64:数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- 数据流中的中位数
- thinkphp3.2链接数据库报No such file or directory错误解决方案
- 封装一个自己的mvc框架
- java面试题(五)
- JAVA 黑白棋
- Boring Game
- 数据流中的中位数
- py-faster-rcnn + ZF 实现自己的数据训练与检测(二)
- PostgreSQL学习篇9.14 XML类型
- nil / Nil / NULL / NSNull
- BZOJ 1711 Dining 吃饭 网络流
- 浅谈二分查找法
- test_one
- C++编译过程常出现的错误
- Java异常简介及其架构