python堆模块_Python 模块源码分析:heapq 堆

起步

heapq 的使用

import heapq

data = [97, 38, 27, 50, 76, 65, 49, 13]

heap = []

for n in data:

heapq.heappush(heap, n)

print('pop:', heapq.heappop(heap)) # pop: 13

print(heap) # [27, 50, 38, 97, 76, 65, 49]

import heapq

data = [97, 38, 27, 50, 76, 65, 49, 13]

heapq.heapify(data)

print('pop:', heapq.heappop(data)) # pop: 13

print(data) # [27, 38, 49, 50, 76, 65, 97]

回顾堆排序算法

如何由一个无序序列建立成一个堆?

如何在输出堆顶元素之后,调整剩余元素,使之成为一个新的堆?

新添加元素和,如何调整堆?

def heapdown(heap, pos):

endpos = len(heap)

while pos < endpos:

lchild = 2 * pos + 1

rchild = 2 * pos + 2

if lchild >= endpos: # 如果pos已经是叶节点,退出循环

break

childpos = lchild # 假设要交换的节点是左节点

if rchild < endpos and heap[childpos] > heap[rchild]:

childpos = rchild

if heap[pos] < heap[childpos]: # 如果节点比子节点都小,退出循环

break

heap[pos], heap[childpos] = heap[childpos], heap[pos] # 交换

pos = childpos

def heapup(heap, startpos, pos): # 如果是新增元素,startpos 传入 0

while pos > startpos:

parentpos = (pos - 1) // 2

if heap[pos] < heap[parentpos]:

heap[pos], heap[parentpos] = heap[parentpos], heap[pos]

pos = parentpos

else:

break

for i in reversed(range(len(data) // 2)):

heapdown(data, i)

heapq 源码分析

def heappush(heap, item):

"""Push item onto heap, maintaining the heap invariant."""

heap.append(item)

_siftdown(heap, 0, len(heap)-1)

def _siftdown(heap, startpos, pos):

newitem = heap[pos]

# Follow the path to the root, moving parents down until finding a place

# newitem fits.

while pos > startpos:

parentpos = (pos - 1) >> 1

parent = heap[parentpos]

if newitem < parent:

heap[pos] = parent

pos = parentpos

continue

break

heap[pos] = newitem

def heappop(heap):

"""Pop the smallest item off the heap, maintaining the heap invariant."""

lastelt = heap.pop() # raises appropriate IndexError if heap is empty

if heap:

returnitem = heap[0]

heap[0] = lastelt

_siftup(heap, 0)

return returnitem

return lastelt

def _siftup(heap, pos):

endpos = len(heap)

startpos = pos

newitem = heap[pos]

# Bubble up the smaller child until hitting a leaf.

childpos = 2*pos + 1 # 左节点,默认替换左节点

while childpos < endpos:

# Set childpos to index of smaller child.

rightpos = childpos + 1 # 右节点

if rightpos < endpos and not heap[childpos] < heap[rightpos]:

childpos = rightpos # 当右节点比较小时,应交换的是右节点

# Move the smaller child up.

heap[pos] = heap[childpos]

pos = childpos

childpos = 2*pos + 1

# The leaf at pos is empty now. Put newitem there, and bubble it up

# to its final resting place (by sifting its parents down).

heap[pos] = newitem

_siftdown(heap, startpos, pos)

def heapify(x):

"""Transform list into a heap, in-place, in O(len(x)) time."""

n = len(x)

for i in reversed(range(n//2)):

_siftup(x, i)

总结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值