求一个无序数组的中位数(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

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值