queue标准库
Python自带的queue标准库可以实现队列、栈、优先队列
import queue
q = queue.Queue()# 队列
#也可用q = queue.Queue(maxsize=5)创建有限大小的队列,用q.full()判断队满
#队满后再入队貌似会卡死,若需“顶出”另一端元素,可用双端队列
stack = queue.LifoQueue()# 栈
pq = queue.PriorityQueue()# 优先队列
================== RESTART: C:\Users\13272\Desktop\最大公约数gcd.py =================
>>> q.put(10)#10入队
>>> q.qsize()#队列大小
1
>>> q.get()#出队并返回队首元素
10
>>> q.empty()#队列是否为空
True
- 栈、优先队列的使用方法与队列类似,也有
put()
、get()
、empty()
、qsize()
等方法 - 优先队列在入队时,优先将值小的元素放在队首
对于数字、字符串等,会自动比较大小
对于元组,优先按第一个值从小到大排,第一个值相同按第二个值从小到大排
然而如果有更复杂的情况,可以自定义一个类,然后在类中重载__lt__
“小于”成员函数,指定比较时采用的规则 - 若需要从大到小排列,可以在入队时,将[元素的负值]入队
例如,输入整数n和n个学生的信息,按照年龄从大到小输出学生信息,若年龄相同则按姓名字典序输出
class Stu:
def __init__(self,name,age):
self.name = name
self.age = age
def __lt__(self,another):
if self.age!=another.age:#若年龄不同,按照年龄从大到小输出
return self.age>another.age
return self.name<another.name#年龄相同,按照姓名从小到大输出
from queue import PriorityQueue
n = int(input())
pq = PriorityQueue()
for i in range(n):
name,age = input().split()
age = int(age)
pq.put(Stu(name,age))
while pq.empty()==False:
student = pq.get()
print(student.name,student.age)
================= RESTART: C:/Users/13272/Desktop/优先队列输出学生名单.py ================
5
Rose 20
Tom 17
Bob 20
Eric 17
Jack 15
Bob 20
Rose 20
Eric 17
Tom 17
Jack 15
heapq标准库
heapq标准库用于实现堆
堆(二叉堆)
- 堆本质上是完全二叉树,由于其特性(左儿子
2*i
,右儿子2*i+1
),直接使用数组来保存更加方便 - 堆近似理解为优先队列,不管元素的插入顺序,总能按照元素的优先级取出元素
- 堆的类型:
最大堆-任意父节点的值一定大于或等于子节点(左右子节点的关系没有要求)
最小堆-任意父节点的值一定小于或等于子节点… - 堆的底层实现:关键在于插入和删除时,利用[siftUp上浮和siftDown下沉]两种核心操作,始终保持最大/最小堆的性质
- 堆的最大优势在于:在查询前n个最大/最小的元素时就有很好的性能
Python中堆的实现
- 首先要明确,堆本质上就是列表
- Python提供heapq标准库,用于操作具有堆性质的【列表】
Python的heapq默认是小顶堆
创建堆、添加元素
- 可以先创建一个空堆,然后用
heappush(heap, num)
将数据一个一个地添加到堆中 - 也可以使用
heapify(list)
使一般的列表转化为堆
>>> from heapq import *
>>> h=[]
>>> heappush(h,4)
>>> heappush(h,7)
>>> heappush(h,3)
>>> heappush(h,2)
>>> heappush(h,8)
>>> h
[2, 3, 4, 7, 8]
>>> h=[4,7,3,2,8]
>>> heapify(h)
>>> h
[2, 4, 3, 7, 8]
删除元素
heappop(heap)
只能弹出堆顶(最小值),且保证剩余的堆仍然是小顶堆
>>> heappop(h)
2
>>> h
[3, 7, 4, 8]
查询堆中前n大/小的几个元素
nlargest(n,heap)
和nsmallest(n,heap)
>>> nlargest(3,h)
[8, 7, 4]
>>> nsmallest(3,h)
[3, 4, 7]
合并两个有序列表
heapq.merge(list1, list2)
用于将两个有序列表合并成一个新的有序列表,返回结果是一个迭代器,这个方法可以用于归并排序
>>> l1=[1,5,8]
>>> l2=[2,3,9]
>>> list(merge(l1,l2))
[1, 2, 3, 5, 8, 9]