有一组元素,它们不断地被动态加入和删除,但是我们需要随时找出当前所以元素的中位数,为此,请设计一个数据结构,以支持对数时间的插入,删除和常数时间的找出中位数,提示:利用两个堆来实现该数据结构,写出完整伪代码并解析
时间: 2024-10-23 09:04:08 浏览: 28
为了实现这样的数据结构,我们可以采用两个大小相同的最小堆(小顶堆)和一个最大堆(大顶堆)。这个设计被称为“双堆”或者“平衡二叉堆”的变种,其中一个堆存储较小的一半元素,另一个堆存储较大的一半元素,并保持它们的中位数位于两者之间。
**伪代码**:
```python
class MedianFinder:
def __init__(self):
self.min_heap = [] # 最小堆,存放较小元素
self.max_heap = [] # 最大堆,存放较大元素
def addNum(self, num):
# 插入操作
if not self.min_heap or num < self.min_heap[0]:
self.min_heap.append(num)
self.max_heap.insert(0, -num) # 对负数进行操作,保持两个堆大小一致
else:
self.min_heap.insert(0, num)
self.max_heap.pop() # 移除最大堆顶部元素,保持大小平衡
self.max_heap.append(-num)
def findMedian(self):
# 查找中位数操作
if len(self.min_heap) == len(self.max_heap): # 两堆大小相等,中位是两者根节点平均值
return (self.min_heap[0] - self.max_heap[0]) / 2.0
else:
return self.min_heap[0] # 当前堆大,中位是堆顶元素
# 使用示例
mf = MedianFinder()
mf.addNum(1)
mf.addNum(2)
print(mf.findMedian()) # 输出: 1.5
mf.addNum(3)
print(mf.findMedian()) # 输出: 2
```
**解析**:
- 在添加元素时,如果新元素小于最小堆的根元素,就直接添加到最小堆;否则,将其添加到最小堆并从最大堆移除相应元素,以保持两个堆大小一致。
- 查找中位数时,如果两个堆的大小相等,则中位数是两个堆顶元素的平均值;若有一个堆大于另一个堆,中位数就是那个大堆的堆顶元素。
这个数据结构使得插入操作在对数时间内完成,查找中位数则始终在常数时间内完成。
阅读全文