数据流中的中位数,奇数个数字时就是排序后的中间数字,偶数个数字时就是排序后中间两个数的平均值
解法一:堆的使用,策略是空间换时间
最小堆和最大堆实现,奇数时放入最大堆,即中位数的左侧,偶数时放入最小堆的右侧,即中位数的右侧
再放入最大堆前,先与最小堆top比较大小,取出小的放入最大堆,反之亦然
获取中位数时,如果当前堆size和为偶数,取两堆top的平均数,如果为奇数,取最小堆的top
解法二:数组存储,快速排序求第K个数值大小,插入O(1),查找O(n)
解法三:排序的链表,插入O(n),取出O(1),中途保存中位数的指针,空间也是O(N)
解法四:二叉平衡搜索树,难
template<typename T> class DynamicArray1 //diy
{
public:
DynamicArray1(){}
~DynamicArray1(){}
void Insert(T value)
{
if ((minHeap.size()+maxHeap.size()) & 1)//已存奇数个,往小顶堆存
{
//to minheap
if (minHeap.size() <= 0 && value > maxHeap.front())
minHeap.push_back(maxHeap.front());
else if (value < maxHeap.front())
{
minHeap.push_back(maxHeap.front());
push_heap(minHeap.begin(), minHeap.end(), greater<T>());
pop_heap(maxHeap.begin(), maxHeap.end(), less<T>());
maxHeap.pop_back();
maxHeap.push_back(value);
push_heap(maxHeap.begin(), maxHeap.end(), less<T>());
}
else
{
minHeap.push_back(value);
push_heap(minHeap.begin(), minHeap.end(), greater<T>());
}
}
else //已存偶数个,
{
//to maxheap
if (maxHeap.size() <= 0)
maxHeap.push_back(value);
else
{
if (value>minHeap.front())
{
maxHeap.push_back(minHeap.front());
push_heap(maxHeap.begin(), maxHeap.end(),less<T>());
pop_heap(minHeap.begin(), minHeap.end(), greater<T>());
minHeap.pop_back();
minHeap.push_back(value);
push_heap(minHeap.begin(), minHeap.end(), greater<T>());
}
else
{
maxHeap.push_back(value);
push_heap(maxHeap.begin(), maxHeap.end(), less<T>());
}
}
}
}
T GetMedian()
{
if ((minHeap.size()+maxHeap.size())&1)
return maxHeap.front();
else if ((minHeap.size() + maxHeap.size())==0)
throw exception("No numbers are available");
else
return (minHeap.front() + maxHeap.front())/2;
}
private:
vector<T> minHeap;//右侧
vector<T> maxHeap;//左侧
};