您当前的位置: 首页 >  Python

IT之一小佬

暂无认证

  • 1浏览

    0关注

    1192博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

python之堆heapq模块

IT之一小佬 发布时间:2021-04-25 16:55:02 ,浏览量:1

python之堆heapq模块

堆是一种特殊的树形结构,通常我们所说的堆的数据结构指的是完全二叉树,并且根节点的值小于等于该节点所有子节点的值。

堆是非线性的树形的数据结构,有两种堆,最大堆与最小堆。( heapq库中的堆默认是最小堆)

  • 最大堆,树种各个父节点的值总是大于或等于任何一个子节点的值。
  • 最小堆,树种各个父节点的值总是小于或等于任何一个子节点的值。

我们一般使用二叉堆来实现优先级队列,它的内部调整算法复杂度为logN。

堆是一个二叉树,其中最小堆每个父节点的值都小于或等于其所有子节点的值。

整个最小堆的最小元素总是位于二叉树的根节点。

常用方法 heappush(heap,item)往堆中插入一条新的值heappop(heap)从堆中弹出最小值heapreplace(heap,item)从堆中弹出最小值,并往堆中插入item   【注意:与heappushpop(heap,item)的区别在于,顺序不同,这里是先进行删除,后压入堆】heappushpop(heap,item)Python3中的heappushpop更高级  【注意:相当于先操作了heappush(heap,item),然后操作heappop(heap)】heapify(x)以线性时间将一个列表转化为堆  【直接会对列表进行排序变成堆排序】merge(*iterables,key=None,reverse=False)合并对个堆,然后输出nlargest(n,iterable,key=None)返回可枚举对象中的n个最大值并返回一个结果集listnsmallest(n,iterable,key=None)返回可枚举对象中的n个最小值并返回一个结果集list 常用方法示例:
import heapq
import random


def test():
    li = list(random.sample(range(100), 6))
    print(li)

    n = len(li)
    # nlargest
    print("nlargest:", heapq.nlargest(n, li))
    # nsmallest
    print("nsmallest:", heapq.nsmallest(n, li))
    # heapify
    print('original list is', li)
    heapq.heapify(li)
    print('heapify  list is', li)
    # heappush & heappop  
    heapq.heappush(li, 105)
    print('pushed heap is', li)
    heapq.heappop(li)
    print('popped heap is', li)
    # heappushpop & heapreplace  
    heapq.heappushpop(li, 130)  # heappush -> heappop
    print('heappushpop', li)
    heapq.heapreplace(li, 2)  # heappop -> heappush
    print('heapreplace', li)


test()

运行结果:

堆排序示例 

heapq模块中有几张方法进行排序:

方法一:

import heapq


def heap_sort(iterable):
    heap = []
    for i in iterable:
        heapq.heappush(heap, i)

    return [heapq.heappop(heap) for _ in range(len(heap))]


if __name__ == '__main__':
    li = [30, 40, 60, 10, 20, 50]
    print(heap_sort(li))

运行结果:

方法二(使用nlargest或nsmallest):

import heapq

li = [30, 40, 60, 10, 20, 50]
# nlargest
n = len(li)
print("nlargest:", heapq.nlargest(n, li))
# nsmallest
print("nsmallest:", heapq.nsmallest(n, li))

运行结果:

方法三(使用heapify):

import heapq


def heap_sort(list):
    print(list)
    heapq.heapify(list)
    print(list)
    heap = []

    while (list):
        heap.append(heapq.heappop(list))

    print(heap)
    li[:] = heap
    print(li)


if __name__ == '__main__':
    li = [30, 40, 60, 10, 20, 50]
    heap_sort(li)

运行结果:

堆在优先级队列中的应用

  需求:实现任务的添加,删除(相当于任务的执行),修改任务优先级

from heapq import *
import itertools

pq = []  # list of entries arranged in a heap
entry_finder = {}  # mapping of tasks to entries
REMOVED = ''  # placeholder for a removed task
counter = itertools.count()  # unique sequence count


def add_task(task, priority=0):
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task(task)
    count = next(counter)
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush(pq, entry)


def remove_task(task):
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop(task)
    entry[-1] = REMOVED


def pop_task():
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop(pq)
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError('pop from an empty priority queue')

 

关注
打赏
1665675218
查看更多评论
立即登录/注册

微信扫码登录

0.1082s