[转载] python中 堆heapq以及 队列queue的使用

参考链接: 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()))

上一篇:剑指 Offer 40. 最小的k个数


下一篇:队列之循环队列