参考链接: Python中的堆队列(Heap queue或heapq)
python中 堆heapq以及 队列queue的使用
1. 堆heapq的使用
## ------------------------ 准备数据 -----------------------
import math
from io import StringIO
data = [19,9,4,10,11]
def show_tree(tree, total_width=36, fill=' '):
output = StringIO()
last_row = -1
for i, n in enumerate(tree):
if i:
row = int(math.floor(math.log(i+1, 2)))
else:
row = 0
if row != last_row:
output.write('\n')
columns = 2 ** row
col_width = int(math.floor(total_width / columns))
output.write(str(n).center(col_width, fill)) # Python center() 返回一个原字符串居中,并使用空格填充至长度 width 的新字符串。默认填充字符为空格。
last_row = row
print(output.getvalue())
print('-' * total_width)
print()
## ---------------------------- 1. 创建堆 ------------------------
# 创建堆有两种基本方式: heapq.heappush() 和 heapq.heapify()
# 1. heapq.heappush()
import heapq # 最小堆
heap = []
print('random : ', data)
print()
for n in data:
print('add {:>3}:'.format(n))
heapq.heappush(heap, n)
show_tree(heap)
# 如果数据已经在内存中,那么使用heapify()原地重新组织列表中的元素会更高效
# 2. heapq.heapify() heapify:堆化
import heapq
print('random :', data)
heapq.heapify(data)
print('heapified :')
show_tree(data)
"""
## ------------------- 2.1 删除元素 --------------------------
for i in range(2):
smallest = heapq.heappop(data)
print('pop {}:'.format(smallest))
show_tree(data)
"""
## ------------------- 2.2 删除并替换新值 --------------------
for n in [0, 13]:
smallest = heapq.heapreplace(data, n)
print('replace {:>2} with {:>2}:'.format(smallest, n) )
show_tree(data)
## ------------------- 3. 查找最大和最小k个数 -------------
# heapq.nlargest() 和 heapq.nsmallest()
import heapq
print()
data = [19,9,4,10,11]
heapq.heapify(data)
print('heaptree: ')
show_tree(data)
print('all :', data, '\n')
print('3 largest :', heapq.nlargest(3, data))
print('from sort :', list(reversed(sorted(data)[-3:])), '\n')
print('3 smallest:', heapq.nsmallest(3, data))
print('from sort :', sorted(data)[:3])
## ------------------- 4. 高效合并有序序列 ------------------
# 对于小数据集,将多个有序序列合并到一个新序列很容易:
import heapq
import itertools
print()
data = [19,9,4,10,11]
heapq.heapify(data)
print('heaptree: ')
show_tree(data)
data2 = list(sorted(itertools.chain(data+data))) # chain()中可以放多个迭代对象,然后一一迭代出来
print('combined tree: ')
show_tree(data2)
# 对于较大的数据集, 这个技术可能会占用大量内存, merge()不是对整个合并后的序列排序,
# 而是使用一个堆一次一个元素地生成一个新序列,利用固定大小的内存确定下一个元素
import random
import heapq
random.seed(2020)
data = []
for i in range(4):
new_data = list(random.sample(range(1,101), 5))
new_data.sort()
data.append(new_data)
for i,d in enumerate(data):
print('{}: {}'.format(i, d))
print('\nMerged:')
for i in heapq.merge(*data):
print(i, end=' ')
print()
2. queue的使用
from queue import Queue,LifoQueue,PriorityQueue
# 先进先出队列
q=Queue()
# 后进先出队列 (通常与栈数据结构关联的)
lq=LifoQueue(maxsize=6)
# 优先级队列
pq=PriorityQueue(maxsize=5)
for i in range(5):
q.put(i) # 使用 put()将元素增加到序列的一端
lq.put(i)
pq.put(i)
print ("先进先出队列:%s;是否为空:%s;多大,%s;是否满,%s" %(q.queue,q.empty(),q.qsize(),q.full()))
print ("后进先出队列:%s;是否为空:%s;多大,%s;是否满,%s" %(lq.queue,lq.empty(),lq.qsize(),lq.full()))
print ("优先级队列:%s;是否为空:%s,多大,%s;是否满,%s" %(pq.queue,pq.empty(),pq.qsize(),pq.full()))
print(q.get(),lq.get(),pq.get()) # 使用 get() 从另一端取出(删除)
print ("先进先出队列:%s;是否为空:%s;多大,%s;是否满,%s" %(q.queue,q.empty(),q.qsize(),q.full()))
print ("后进先出队列:%s;是否为空:%s;多大,%s;是否满,%s" %(lq.queue,lq.empty(),lq.qsize(),lq.full()))
print ("优先级队列:%s;是否为空:%s,多大,%s;是否满,%s" %(pq.queue,pq.empty(),pq.qsize(),pq.full()))