排序取中位数
最容易想到的思路就是直接将所有数据进行排序,然后取排序之后的中位数
不过具体的排序思路也有几种
- 插入排序。在新的数据到达时插入有序序列
- 平衡二叉树。插入平衡二叉树,然后取中位数
最大堆最小堆
创建一个最小堆和最大堆,其中最小堆的最小值比最大堆的最大值还大,并使最小堆最大堆数量保持均衡,那么中位数边取乎于最小最大堆堆顶
// MinHeap is a min-heap implementation.
type MinHeap []int
// Len returns the length of the heap.
func (h MinHeap) Len() int { return len(h) }
// Less compares two elements in the heap.
func (h MinHeap) Less(i, j int) bool { return h[i] < h[j] }
// Swap swaps two elements in the heap.
func (h MinHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
// Push adds an element to the heap.
func (h *MinHeap) Push(x interface{}) {
*h = append(*h, x.(int))
}
// Pop removes and returns the smallest element from the heap.
func (h *MinHeap) Pop() interface{} {
old := *h
n := len(old)
x := old[n-1]
*h = old[0 : n-1]
return x
}
// MaxHeap is a max-heap implementation.
type MaxHeap []int
// Len returns the length of the heap.
func (h MaxHeap) Len() int { return len(h) }
// Less compares two elements in the heap.
func (h MaxHeap) Less(i, j int) bool { return h[i] > h[j] }
// Swap swaps two elements in the heap.
func (h MaxHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
// Push adds an element to the heap.
func (h *MaxHeap) Push(x interface{}) {
*h = append(*h, x.(int))
}
// Pop removes and returns the largest element from the heap.
func (h *MaxHeap) Pop() interface{} {
old := *h
n := len(old)
x := old[n-1]
*h = old[0 : n-1]
return x
}
// StreamingMedianCalculator calculates the median from a continuous stream of input data.
type StreamingMedianCalculator struct {
minHeap MinHeap
maxHeap MaxHeap
}
// AddData adds a new data point to the calculator.
func (s *StreamingMedianCalculator) AddData(data int) {
// 加入到对应堆,以是否大于最小堆顶值为区分
if len(s.minHeap) == 0 || data >= s.minHeap[0] {
heap.Push(&s.minHeap, data)
} else {
heap.Push(&s.maxHeap, data)
}
// 均衡两堆数量
if len(s.minHeap)-len(s.maxHeap) > 1 {
heap.Push(&s.maxHeap, heap.Pop(&s.minHeap))
} else if len(s.maxHeap)-len(s.minHeap) > 1 {
heap.Push(&s.minHeap, heap.Pop(&s.maxHeap))
}
}
// GetMedian returns the current median.
func (s *StreamingMedianCalculator) GetMedian() float64 {
if len(s.minHeap) == len(s.maxHeap) {
return float64(s.minHeap[0]+s.maxHeap[0]) / 2
} else if len(s.minHeap) > len(s.maxHeap) {
return float64(s.minHeap[0])
} else {
return float64(s.maxHeap[0])
}
}