1. 简介
优先队列是一种特殊的队列,队列中的元素按照其优先级进行排序。优先级可以由元素自身的值决定,也可以由自定义的比较规则决定。在 Python 中,可以通过 queue 模块中的 PriorityQueue 类来实现优先队列。PriorityQueue 类内部使用堆结构来实现,保证每次出队操作都能获取到优先级最高的元素。
优先队列在许多场景中都非常有用,例如任务调度(高优先级任务先执行)、消息队列(重要消息先处理)、Dijkstra 算法(最短路径优先)等。
2. PriorityQueue 类的基本操作
队列的操作其实很多都是相同或相似的,比如入队,出队等操作。只是每个特定操作可能有一些不同。
(1)创建队列
使用 queue.PriorityQueue() 可以创建一个优先队列。可以通过设置 maxsize 参数来指定队列的最大容量。如果 maxsize 小于或等于 0,则队列大小无限。
样例:
import queue
# 创建一个空的优先队列,最大容量为 3
priority_queue = queue.PriorityQueue(maxsize=3)
print("创建的优先队列:", priority_queue)程序运行结果:
(2)入队(向队列中添加元素)
- put(item, block=True, timeout=None)
将元素 item 放入队列中。如果队列已满,且 block 参数为 True,则线程会阻塞,直到队列有空间。如果 block 为 False,则会抛出 queue.Full 异常。timeout 参数指定线程阻塞等待的时间,单位为秒。
在优先队列中,元素通常是元组形式,例如 (优先级, 数据),队列会根据元组的第一个元素(优先级)进行排序。优先级数字越小的元素优先级越高,会先出队。优先级数字越小优先级就越高!!!
import queue
priority_queue = queue.PriorityQueue(maxsize=3)
# 向队列中添加元素(元组形式,第一个元素为优先级)
print("初始队列是否为空:", priority_queue.empty())
priority_queue.put((1, "陪赔家人"))
priority_queue.put((2, "挣money"))
priority_queue.put((3, "吃喝玩乐"))
# 尝试继续添加元素(阻塞,此处会等待直到有空间)
# priority_queue.put((4, "睡觉"), block=True, timeout=5)
print("队列元素(按优先级排序):")
for _ in range(priority_queue.qsize()):
print(priority_queue.queue[_])程序运行结果:
可以看出先输出的是1,陪陪家人,其次是2 挣money,最后是吃喝玩乐。题外话(1我相信应该是最重要的,但是现实中往往大多数人看中的是2。)
(3)出队
- get(block=True, timeout=None)
从队列中移除并返回优先级最高的元素**。如果队列为空,且 block 参数为 True,则线程会阻塞,直到队列有元素。如果 block 为 False,则会抛出 queue.Empty 异常。timeout 参数指定线程阻塞等待的时间,单位为秒。
样例:
import queue
priority_queue = queue.PriorityQueue(maxsize=3)
priority_queue.put((1, "陪赔家人"))
priority_queue.put((2, "挣money"))
priority_queue.put((3, "吃喝玩乐"))
# 从队列中移除元素(按优先级顺序)
print("出队的元素:")
while not priority_queue.empty():
item = priority_queue.get()
print(item)程序运行结果:
(4)队列状态
- empty()
如果队列为空,返回 True;否则返回 False。
- full()
如果队列已满,返回 True;否则返回 False。
样例:
import queue
priority_queue = queue.PriorityQueue(maxsize=3)
# 判断队列是否为空
print("队列是否为空:", priority_queue.empty())
# 向队列中添加元素
priority_queue.put((1, "陪赔家人"))
priority_queue.put((2, "挣money"))
priority_queue.put((3, "吃喝玩乐"))
# 判断队列是否已满
print("队列是否已满:", priority_queue.full())
# 移除一个元素后,判断队列状态
priority_queue.get()
print("移除一个元素后,队列是否为空:", priority_queue.empty())
print("移除一个元素后,队列是否已满:", priority_queue.full())程序运行结果:
(5)队列大小
- qsize()
返回队列中元素的大致数量。
样例:
import queue
priority_queue = queue.PriorityQueue(maxsize=3)
# 获取队列初始大小
print("队列初始大小:", priority_queue.qsize())
# 向队列中添加元素并获取队列大小
priority_queue.put((1, "陪陪家人"))
print("添加一个元素后队列大小:", priority_queue.qsize())
priority_queue.put((2, "挣money"))
priority_queue.put((3, "吃喝玩乐"))
print("添加三个元素后队列大小:", priority_queue.qsize())程序运行结果:
3. 总结
优先队列是一种重要的数据结构,可以通过 queue 模块中的 PriorityQueue 类来实现。它的主要特点是元素按照优先级进行排序,每次出队操作都能获取到优先级最高的元素,优先级数字越小代表优先级越高。优先队列适用于任务调度、Dijkstra 算法、事件驱动模拟等多种场景。
PriorityQueue 类的常用方法包括 put()(入队)、get()(出队)、empty()(判断队列是否为空)、full()(判断队列是否已满)和 qsize()(获取队列大小)。通过这些方法,可以在多线程环境下安全地操作优先队列。
