转自 http://blog.sina.com.cn/s/blog_455b20c10100fmmb.html
问题陈述:有个需要动态更新(插入或删除)的数列L,现在需要随时获取到该数列的中位数,请设计相应的数据结构和算法。
算法:令L的中位数为m,用一个大顶堆存储数列L中不大于m的元素(即L按从小到大排列时的前半部分),用一个小顶堆存储数列L中不小于m的元素(即L按从小到大排列时的后半部分),其中这两个大小顶堆均不包含中位数m。每次往数列L插入新元素x时,若x<m,则将其插入大顶堆,否则插入小顶堆。若插入新元素后导致m不再是中位数(即两个堆的元素数目相差2个或2个以上),则将当前的中位数m插入到元素数量较少的那个堆中,然后令元素数量较多的那个堆的堆顶元素为新的中位数,并从该堆顶元素从堆中删除。
分析:容易看出,以上算法中,读取当前中位数的时间复杂度为O(1),插入和删除元素(包括调整堆)的时间复杂度为O(logN)。
发散:上述算法可以推广到解决维护数列的第k大(小)数的问题,只需要修改大、小顶堆的元素数目即可。