无序数组的中位数
不能使用排序算法,而且要求时间复杂度O(n)。
# -*- coding: utf-8 -*-
# @Time : 2019/4/22 10:42 AM
# @Author : George
# @File : main7.py
# @Contact : [email protected]
def heapify(seq, start, end):
"""
找出从start到end的范围内的最小值,放在堆顶的位置
:param seq:
:param start:
:param end:
:return:
"""
# start结点的左右子结点
left, right = 2 * start + 1, 2 * (start + 1)
mi = start
# 从左右子结点中选出最小值
if left < end and seq[mi] > seq[left]:
mi = left
if right < end and seq[mi] > seq[right]:
mi = right
if mi != start:
# 找到最小值后调整位置
seq[start], seq[mi] = seq[mi], seq[start]
heapify(seq, mi, end)
def find_mid_num(nums):
heap_num = len(nums)//2
heap = nums[:heap_num+1]
# 建立最小堆
start, end = len(heap) // 2 - 1, len(heap)
for i in range(len(heap)//2-1, -1, -1): # 前n/2个元素建堆
heapify(heap, i, end)
# 将原数组后面一般的数据一一和堆顶进行比较,大于堆顶则替换掉
# 原理就是替换掉一般的数值,剩下的堆顶就是中位数
for j in range(heap_num + 1, len(nums)):
if nums[j] > heap[0]:
# 堆顶被替换掉
print '堆顶%s被替换成%s' % (heap[0], nums[j])
heap[0] = nums[j]
heapify(heap, 0, end)
# 奇数时是最中间的数,偶数时是最中间两数的均值
return heap[0] if len(nums) % 2 else (heap[0] + min(heap[1], heap[2])) / 2.0