Python标准库模块heapq_堆

目录

堆的概念

堆结题的基本技巧: 

heapq堆的常用方法:

heapq.heapify(list)

heapq.heappush(heap, item)

heapq.heappop(heap) 

 heapq.heapreplace(heap.item) 

heapq.heappushpop(heap, item)

heapq.merge(*iterables, key=None, reverse=False) 

heapq.nlargest(n, iterable, key=None) 

heapq.nsmallest(n,iterable, key=None)


堆的概念

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

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

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

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

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

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

python的heapq模块提供了对堆的支持。 heapq堆数据结构最重要的特征是heap[0]永远是最小的元素

Python标准库模块heapq_堆_第1张图片

堆结题的基本技巧: 

常用方法:nlargest(),nsmallest(),heapify(),heappop() 

如果需要的个数较小,使用nlargest或者nsmallest比较好

如果需要的个数已经接近了序列长度,使用sorted()[:N]获取前N个数据比较好 

如果只需要唯一一个最大或最小值,则直接使用max()或者min()

heapq堆的常用方法:

heapq.heapify(list)

将列表转换为最小堆 ,转换完后仍然是列表,所以heapify只是对列表中的元素进行了堆属性的排序

import heapq
res=[7,1,5,4,2,3]
print("列表",res,type(res))     #列表 [7, 1, 5, 4, 2, 3] 
heapq.heapify(res)
print("最小堆",res,type(res))   #最小堆 [1, 2, 3, 4, 7, 5] 

heapq.heappush(heap, item)

将元素item压入heap堆(列表)中

import heapq
res=[7,1,5,6,2,3]
heapq.heapify(res)
heapq.heappush(res,8)
print("最小堆",res,type(res))   #最小堆 [1, 2, 3, 6, 7, 5, 8] 

heapq.heappop(heap) 

删除并返回最小值,因为堆的特征是heap[0]永远是最小的元素,所以一般都是删除第一个元素。故,需要先通过heapify(list) 将list转变为heap。

import heapq
res=[7,1,5,6,2,3]
print("列表",res,type(res))      #列表 [7, 1, 5, 6, 2, 3] 
heapq.heapify(res)
min_d=heapq.heappop(res)
print(min_d)                     #1
print("最小堆",res,type(res))    #最小堆 [2, 5, 3, 6, 7] 

 heapq.heapreplace(heap.item) 

删除并返回最小值(堆顶元素),然后将压入的元素放到堆顶,进行最小堆排序,得到最终的结果

import heapq
res=[7,1,5,6,2,3]
heapq.heapify(res)
pop_item=heapq.heapreplace(res,8)
print(pop_item)                      #1
print("最小堆",res,type(res))        #最小堆 [2, 6, 3, 8, 7, 5] 

heapq.heappushpop(heap, item)

如果item小于等于堆最小值(堆顶元素)——返回item,堆不进行更改

如果item大于堆最小值(堆顶元素)——删除并返回最小值(堆顶元素),然后将压入的元素放到堆顶,进行最小堆排序,得到最终的结果

import heapq
res=[7,1,5,6,2,3]
heapq.heapify(res)
pop_item=heapq.heappushpop(res,8)
print(pop_item)                    # 1
print("最小堆",res,type(res))      #最小堆 [2, 6, 3, 8, 7, 5] 

说明:以下函数,参数可以是堆,也可以是列表等其他可迭代对象


heapq.merge(*iterables, key=None, reverse=False) 

实现归并排序 ;reverse:排序方式顺序/逆序;key:排序关键字;

1、heapq.merge()的迭代性质意味着它对所有提供的序列都不会做一次性读取。这意味着可以利用它处理非常长的序列,而开销却非常小;
2、heapq.merge()要求所有的输入序列都是有序的,它只是简单地检查每个输入序列中的第一个元素,将最小的那个发送出去,然后重复执行这个步骤,直到所有的输入序列都耗尽为止。

import heapq
res=[7,1,5,6,2,3]
res1=[4,8,9]
heapq.heapify(res1)
heapq.heapify(res)
print(res)                             #[1, 2, 3, 6, 7, 5]
print(res1)                            #[4, 8, 9]
pop_item=list(heapq.merge(res,res1))
print(pop_item)                        #[1, 2, 3, 4, 6, 7, 5, 8, 9]
print("最小堆",res,type(res))           #最小堆 [1, 2, 3, 6, 7, 5] 

heapq.nlargest(n, iterable, key=None) 

查询iterable中的n个最大的元素,且返回的列表从大到小排序;

import heapq
res=[4,7,1,5,6,2,3,8,12]
largest_item=heapq.nlargest(4,res)
print(largest_item)                 #[12, 8, 7, 6]

heapq.nsmallest(n,iterable, key=None)

查询iterable中的n个最小的元素,且返回的列表从小到大排序;

import heapq
res=[4,7,1,5,6,2,3,8,12]
small_item=heapq.nsmallest(4,res)
print(small_item)                 #[1, 2, 3, 4]

 

你可能感兴趣的:(python,heapq,堆)