求一个无序数组的中位数(Python)

最简单的方法是先将数组排序,然后找中位数。但此种方法肯定不是最优的。一个比较好的做法是利用小顶堆。思路如下:

1.取前len(nums)/2个元素建立小顶堆。可以知道堆顶元素是前len(nums)/2个元素中最小的。

2.从第len(nums)/2+1个元素开始,依次将其与堆顶元素比较。若比对顶元素大,则替换之,并调整堆。

3.数组剩下的所有元素比较完后,可以输出中位数。数组长度为奇数时,输出堆顶元素即可。数组长度为偶数时,输出堆顶元素与它的孩子结点中较小的那个的均值。

代码如下:

#coding:utf-8

def heap_adjust(parent,heap):   #更新结点后进行调整
    child=2*parent+1
    while len(heap)>child:
        if child+1<len(heap):
            if heap[child+1]<heap[child]:
                child+=1
        if heap[parent]<=heap[child]:
            break
        heap[parent],heap[child]=heap[child],heap[parent]
        parent,child=child,child*2+1

def find(nums):
    heapnum=len(nums)//2
    heap=nums[:heapnum+1]
    for i in range(len(heap)//2-1,-1,-1):   #前n/2个元素建堆
        heap_adjust(i,heap)
    for j in range(heapnum+1,len(nums)):
        if nums[j]>heap[0]:
            heap[0]=nums[j]
            heap_adjust(0,heap)
    #奇数时是最中间的数,偶数时是最中间两数的均值
    return heap[0] if len(nums)%2==1 else float(heap[0]+min(heap[1],heap[2]))/2


猜你喜欢

转载自blog.csdn.net/baike33/article/details/81011395