Python 数据流中的中位数

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.littlevalueMaxHeap = []
        self.bigvalueMinHeap = []
        self.maxHeapCount = 0
        self.minHeapCount = 0

    def Insert(self, num):
        if self.minHeapCount < self.maxHeapCount:
            self.minHeapCount +=1
            if num < self.littlevalueMaxHeap[0]:
                tmpNum = self.littlevalueMaxHeap[0]
                self.adjustMaxHeap(num)
                self.createMinHeap(tmpNum)
            else:
                self.createMinHeap(num)
        else:
            self.maxHeapCount+=1
            if len(self.littlevalueMaxHeap)==0:
                self.createMaxHeap(num)
            else:
               if self.bigvalueMinHeap[0]<num:
                    tmpNum=self.bigvalueMinHeap[0]
                    self.adjustMinHeap(num)
                    self.createMaxHeap(tmpNum)
               else:
                   self.createMaxHeap(num)


    def GetMedian(self):
        if self.minHeapCount<self.maxHeapCount:
            return self.littlevalueMaxHeap[0]
        else:
            return (self.littlevalueMaxHeap[0]+self.bigvalueMinHeap[0])/2

    def createMaxHeap(self, num):
        self.littlevalueMaxHeap.append(num)
        tmpIndex = len(self.littlevalueMaxHeap) - 1
        while tmpIndex:
            parentIndex = (tmpIndex - 1) // 2
            if self.littlevalueMaxHeap[parentIndex] < self.littlevalueMaxHeap[tmpIndex]:
                self.littlevalueMaxHeap[parentIndex], self.littlevalueMaxHeap[tmpIndex] =\
                    self.littlevalueMaxHeap[tmpIndex], self.littlevalueMaxHeap[parentIndex]
                tmpIndex=parentIndex
            else:
                break

    def adjustMaxHeap(self,num):
        if num<self.littlevalueMaxHeap[0]:
            self.littlevalueMaxHeap[0]=num
            maxHeapLen = len(self.littlevalueMaxHeap)
            tmpIndex=0
            while tmpIndex< maxHeapLen:
                leftIndex = tmpIndex*2+1
                rightIndex = tmpIndex*2+2
                largerIndex = 0
                if rightIndex <  maxHeapLen:
                    largerIndex = rightIndex if self.littlevalueMaxHeap[leftIndex]<self.littlevalueMaxHeap[rightIndex] else leftIndex
                elif leftIndex < maxHeapLen:
                    largerIndex = leftIndex
                else:
                    break

                if self.littlevalueMaxHeap[tmpIndex] <self.littlevalueMaxHeap[largerIndex]:
                    self.littlevalueMaxHeap[tmpIndex], self.littlevalueMaxHeap[largerIndex] = self.littlevalueMaxHeap[largerIndex], self.littlevalueMaxHeap[tmpIndex]
                    tmpIndex = largerIndex
                else:
                    break


    def createMinHeap(self, num):
        self.bigvalueMinHeap.append(num)
        tmpIndex = len(self.bigvalueMinHeap) - 1
        while tmpIndex:
            parentIndex = (tmpIndex - 1) // 2
            if self.bigvalueMinHeap[tmpIndex]<self.bigvalueMinHeap[parentIndex] :
                self.bigvalueMinHeap[parentIndex], self.bigvalueMinHeap[tmpIndex] = \
                    self.bigvalueMinHeap[tmpIndex], self.bigvalueMinHeap[parentIndex]
                tmpIndex=parentIndex
            else:
                break

    def adjustMinHeap(self,num):
        if num<self.bigvalueMinHeap[0]:
            self.bigvalueMinHeap[0]=num
            minHeapLen = len(self.bigvalueMinHeap)
            tmpIndex=0
            while tmpIndex< minHeapLen:
                leftIndex = tmpIndex*2+1
                rightIndex = tmpIndex*2+2
                smallerIndex = 0
                if rightIndex <  minHeapLen:
                    smallerIndex = rightIndex if self.bigvalueMinHeap[rightIndex]<self.bigvalueMinHeap[leftIndex] else leftIndex
                elif leftIndex < minHeapLen:
                    smallerIndex = leftIndex
                else:
                    break

                if self.bigvalueMinHeap[smallerIndex] < self.bigvalueMinHeap[tmpIndex]:
                    self.bigvalueMinHeap[tmpIndex], self.bigvalueMinHeap[smallerIndex] = self.bigvalueMinHeap[smallerIndex], self.littlevalueMaxHeap[tmpIndex]
                    tmpIndex = smallerIndex
                else:
                    break


if __name__ == '__main__':
    s=Solution()
    for i in [5,2,3,4,1,6,7,0,8]:
        s.Insert(i)
        print(s.GetMedian())

运行结果为:

5
3.5
3
3.5
3
3.5
4
3.5
4

将以上代码封装,简洁后的代码:

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.littlevalueMaxHeap = []
        self.bigvalueMinHeap = []
        self.maxHeapCount = 0
        self.minHeapCount = 0

    def Insert(self, num):
        def cmpMaxHeap(a, b):
            return a > b

        def cmpMinHeap(a, b):
            return a < b

        if self.minHeapCount < self.maxHeapCount:
            self.minHeapCount += 1
            if num < self.littlevalueMaxHeap[0]:
                tmpNum = self.littlevalueMaxHeap[0]
                self.adjustHeap(num, self.littlevalueMaxHeap, cmpMaxHeap)
                self.createHeap(tmpNum, self.bigvalueMinHeap, cmpMinHeap)
            else:
                self.createHeap(num, self.bigvalueMinHeap, cmpMinHeap)
        else:
            self.maxHeapCount += 1
            if len(self.littlevalueMaxHeap) == 0:
                self.createHeap(num, self.littlevalueMaxHeap, cmpMaxHeap)
            else:
                if self.bigvalueMinHeap[0] < num:
                    tmpNum = self.bigvalueMinHeap[0]
                    self.adjustHeap(num, self.bigvalueMinHeap, cmpMinHeap)
                    self.createHeap(tmpNum, self.littlevalueMaxHeap, cmpMaxHeap)
                else:
                    self.createHeap(num, self.littlevalueMaxHeap, cmpMaxHeap)

    def GetMedian(self):
        if self.minHeapCount < self.maxHeapCount:
            return self.littlevalueMaxHeap[0]
        else:
            return (self.littlevalueMaxHeap[0] + self.bigvalueMinHeap[0]) / 2

    def createHeap(self, num, heap, cmpfun):
        heap.append(num)
        tmpIndex = len(heap) - 1
        while tmpIndex:
            parentIndex = (tmpIndex - 1) // 2
            if cmpfun(heap[tmpIndex], heap[parentIndex]):
                heap[parentIndex], heap[tmpIndex] = heap[tmpIndex], heap[parentIndex]
                tmpIndex = parentIndex
            else:
                break

    def adjustHeap(self, num, heap, cmpFunc):
        if num < heap[0]:
            heap[0] = num
            maxHeapLen = len(heap)
            tmpIndex = 0
            while tmpIndex < maxHeapLen:
                leftIndex = tmpIndex * 2 + 1
                rightIndex = tmpIndex * 2 + 2
                largerIndex = 0
                if rightIndex < maxHeapLen:
                    largerIndex = rightIndex if cmpFunc(heap[rightIndex], heap[leftIndex]) else leftIndex
                elif leftIndex < maxHeapLen:
                    largerIndex = leftIndex
                else:
                    break

                if cmpFunc(heap[largerIndex], heap[tmpIndex]):
                    heap[tmpIndex], heap[largerIndex] = heap[largerIndex], heap[tmpIndex]
                    tmpIndex = largerIndex
                else:
                    break


if __name__ == '__main__':
    s = Solution()
    for i in [5, 2, 3, 4, 1, 6, 7, 0, 8]:
        s.Insert(i)
        print(s.GetMedian())

运行结果为:

5
3.5
3
3.5
3
3.5
4
3.5
4
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值