-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path41_StreamMedian.cpp
More file actions
144 lines (114 loc) · 3.5 KB
/
41_StreamMedian.cpp
File metadata and controls
144 lines (114 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*******************************************************************
Copyright(c) 2016, Harry He
All rights reserved.
Distributed under the BSD license.
(See accompanying file LICENSE.txt at
https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
*******************************************************************/
//==================================================================
// 《剑指Offer——名企面试官精讲典型编程题》代码
// 作者:何海涛
//==================================================================
// 面试题41:数据流中的中位数
// 题目:如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么
// 中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,
// 那么中位数就是所有数值排序之后中间两个数的平均值。
#include <cstdio>
#include <algorithm>
#include <vector>
#include <functional>
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];
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");
throw logic_error("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(char* testName, DynamicArray<double>& numbers, double expected)
{
if(testName != nullptr)
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(const exception&)
{
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;
}