1.堆的向下调整函数
def sift(ls,low,high): #low:堆的根节点位置,high:堆的最后一个元素位置
i=low
j=i*2+1 #最开始指向左孩子
tmp=ls[low] #存下堆顶
while j<high: #只要j位置有数
if j+1<=high and ls[j+1]>ls[j] #右孩子数大
j=j+1 #j指向右孩子
if ls[j]>tmp:
ls[i]=ls[j]
i=j #往下一层
j=i*2+1
else: #tmp更大,把tmp放在i的位置
ls[i]=tmp #把tmp放在某一级领导位置
break
else:
LS[i]=tmp #把tmp放在叶子节点上
2.堆排序函数:
def heap_sort(ls):
n=len(ls)
for i in range((n-2)//2,-1,-1): #表示建堆时调整的部分的根下标
sift(ls,i,n-1) #堆建成
for i in range(n-1,-1,-1): #i指向当前堆的最后一个元素
ls[0],ls[i]=ls[i],ls[0]
sift(ls,0,i-1) #i-1是新的high
3.内置模块heapq
import heqpq #q->quene优先队列
import random
ls=list(range(100))
random.shuffle(ls)
heapq.heapify(ls) #建堆
heapq.heappop(ls)
4.topk问题
题目:现有n个数,得到前k大的的数,(k<n)
思路:
排序后切片 O(nlogn)
排序lowB三人组O(Kn)
堆排序O(nlogK)
堆排序思路:
取列表前K个元素建立一个小根堆,堆顶就是目前第K大的数。、
依次遍历原列表,列表中的元素若大于堆顶,忽略。若大于堆顶,更换堆顶元素
遍历列表所有元素后,倒序弹出堆顶
def topk(ls,k):
heap=ls[0:k]
for i in range((k-2)//2,-1,-1):
sift(heap,i,k-1) #建堆
for i in range(k,len(ls)-1):
if ls[i]>ls[j]:
heap[0]=la[i]
sift(heap,0,k-1) #遍历
for i in range(k-1,-1,-1):
heap[0],heap[i]=heap[i],heap[0]
sift(ls,0,i-1) #出数
return heap