持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情
一、题目
描述
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
#include <iostream>
using namespace std;
class YuanDad {
public:
void Insert(int num) {
}
double GetMedian() {
}
};
int main(int, char*[])
{
YuanDad object;
object.Insert(5);
cout << "right: " << "5.0" << ",real: " << object.GetMedian() << endl;
object.Insert(2);
cout << "right: " << "3.5" << ",real: " << object.GetMedian() << endl;
object.Insert(3);
cout << "right: " << "3.0" << ",real: " << object.GetMedian() << endl;
object.Insert(4);
cout << "right: " << "3.5" << ",real: " << object.GetMedian() << endl;
object.Insert(1);
cout << "right: " << "3.0" << ",real: " << object.GetMedian() << endl;
object.Insert(6);
cout << "right: " << "3.5" << ",real: " << object.GetMedian() << endl;
object.Insert(7);
cout << "right: " << "4.0" << ",real: " << object.GetMedian() << endl;
object.Insert(0);
cout << "right: " << "3.5" << ",real: " << object.GetMedian() << endl;
object.Insert(8);
cout << "right: " << "4.0" << ",real: " << object.GetMedian() << endl;
}
二、分析
由题意可知,要获取数据流中的中位数,就离不开排序。
有序排序算法肯定离不开二分插入排序,但是这里我决定用另一种方法,更直观,更好的理解这道题解题的原理。
我们所要得到的结果是中位数,随意可以记录中间结点,然后直接对中间节点进行比较,拿值,因为不管是偶数还是奇数,我们都只需要关心中间的一个/两个数。
三、模拟
- 5
中间节点: 5
中位数:5 - 2, 5
中间节点: 2和5的平均值
中位数: 3.5 - 2, 3, 5
中间节点: 3
中位数: 3 - 2, 3, 4, 5
中间节点: 3和4的平均值
中位数: 3.5 - 1, 2, 3, 4, 5
中间节点: 3
中位数: 3 - 1, 2, 3, 4, 5, 6
中间节点: 3和4的平均值
中位数: 3.5 - 1, 2, 3, 4, 5, 6, 7
中间节点: 4
中位数: 4 - 0, 1, 2, 3, 4, 5, 6, 7
中间节点: 3和4的平均值
中位数: 3.5 - 0, 1, 2, 3, 4, 5, 6, 7, 8
中间节点: 4
中位数: 4
四、实现
class YuanDads {
public:
struct QyList{
explicit inline QyList(int val): val(val) {}
void left(QyList* other){ if(pre) pre->next = other; other->pre = pre; pre = other; other->next = this;}
void right(QyList* other){ if(next) next->pre = other; other->next = next; next = other; other->pre = this; }
int val;
QyList* pre = nullptr;
QyList* next = nullptr;
};
QyList *min = nullptr, *max = nullptr, *median = nullptr;
bool odd = false;
void Insert(int num) {
odd = !odd;
QyList* node = new QyList(num);
if(odd){
if(median){
if(num < min->val){
QyList* temp = min;
while(temp->pre && temp->pre->val > num) temp = temp->pre;
temp->left(node);
median = min;
min = min->pre;
}else if(num > max->val){
QyList* temp = max;
while(temp->next && temp->next->val < num) temp = temp->next;
temp->right(node);
median = max;
max = max->next;
}else{
median = node;
min->right(median);
}
}else{
median = node;
}
}else{
if(num < median->val){
if(min){
QyList* temp = median;
while(temp->pre && temp->pre->val > num) temp = temp->pre;
temp->left(node);
max = median;
min = median->pre;
}else{
min = node;
max = median;
max->left(min);
}
}else{
if(min){
QyList* temp = median;
while(temp->next && temp->next->val < num) temp = temp->next;
temp->right(node);
min = median;
max = median->next;
}else{
max = node;
min = median;
min->right(max);
}
}
}
}
double GetMedian() {
if(odd){
return static_cast<double>(median->val);
}else{
return (min->val + max->val) / 2.0;
}
}
};
五、结言
理解为主
创作不易,留个赞再走吧!如果对文章内容有任何指正,欢迎评论!