python堆栈与队列_python内置的堆、栈和队列

本文用于介绍python中内置的堆、栈和队列结构方法,并且计较这些方法的差异与使用场景。

heapq 堆队列

heapq 是一个内置堆结构,一种特殊形式的完全二叉树,其中父节点的值总是大于子节点,根据其性质,python可以用一个满足 heap[k] <= heap[2 * k + 1] <= heap[2 * k + 2] 的列表来实现。heapq是最小堆,如果要实现最大堆,可以使用一些小诀窍,例如在heappush的时候,填进去的是 数据 * -1,然后heappop的时候,将弹出的元素乘以-1即可

import heapq

heap = []

heapq.heappush(heap, 3)

heapq.heappush(heap, 2)

heapq.heappush(heap, 1)

print(heap) # 输出为 [1, 3, 2]

# 要想有序输出 堆的元素

heapq.heappop(heap) # 输出1

heapq.heappop(heap) # 输出2

heapq.heappop(heap) # 输出3

# 要想输出前n个最大值,前n个最小值,可以使用

heapq.nlargest(n, heap)

heapq.nsmallest(n, heap)

deque 双端队列

from collections import deque 可以实现栈也可以实现队列的功能,因为双端队列可以在队列的头部和尾部进行编辑,所以我们如果想要在python中实现栈的功能的话,最好的选择是deque,当然我们也可以使用普通的数组结构。

普通的队列操作,就是在队尾插入元素,然后队头弹出元素:

dq = queue()

dq.append(3) # deque([3])

dq.append(4) # deque([3, 4])

dq.popleft() # 弹出 3,并且dq为 deque([4])

如果设置为一个栈的话,FILO,那么就是如下的代码

dq = queue()

dq.append(3) # deque([3])

dq.append(4) # deque([3, 4])

dq.pop() # 弹出 4,并且dq为 deque([3])

queue

queue队列是一个线程安全的包,这个包里面有很多的结构,比如栈 LifoQueue ,如果要在并发环境下使用的话,最好使用这个结构,因为如果栈为空的情况下,去弹出栈顶元素的话,会出现阻塞现象,知道栈不为空为止

LifoQueue

LifoQueue 是一个栈结构,有入栈和出战操作,方法分别是 put() 和 get(),并且 get() 在 LifoQueue() 为空时会阻塞

from queue import LifoQueue

s = LifoQueue()

s.put(3)

s.put(4)

print(s.get()) # 打印4

print(s.get()) # 打印3

print(s.get()) # 一直等待直到s中存在元素,然后就打印退出

Queue

Queue 是一个队列,有入队和出队操作,方法分别是 put() 和 get(),并且 get() 在 Queue 为空时会阻塞,另外也可以设置队列的长度,如果没有设置队列的长度,或者设置队列的长度为小于等于0的数,那么表示队列的长度为无限,可以通过 .maxsize 属性来获取队列的最大长度

from queue import Queue

q = Queue()

q.put(3)

q.put(4)

print(q.get()) # 打印3

print(q.get()) # 打印4

print(q.get()) # 一直等待直到q中存在元素,然后就打印退出

print(q.get_nowait()) # 如果队列q为空,那么不会等待,而是输出 Empty 的异常

PriorityQueue

PriorityQueue 是一个优先队列,队列的元素是排好序了的,所以针对一个排序的序列可以使用优先队列,它能高效获取最大或最小的元素。

在调度问题的场景中,经常用到优先级队列,它主要有获取最大值或最小值的操作和入队操作

优先队列,是内部封装了 heapq,不同的是优先队列是线程安全的,在并发环境下应该选择使用 PriorityQueue

from queue import PriorityQueue

pq = PriorityQueue()

pq.put((2, 'name'))

pq.put((1, 'age'))

pq.put((3, 'job'))

while not pq.empty():

print(pq.get())

"""

输出内容如下

(1, "age")

(2, "name")

(3, "job")

"""

multiprocessing.Queue

多进程版本的队列 multiprocessing.Quque,如果要在多进程环境下使用队列,那么应该选择 multiprocessing.Queue

同样的,它的入队出队操作分别是 put() 和 get()。

汇总如下

对象

使用的包

使用场景

说明

heapq

单线程堆

最小堆

queue.PriorityQueue

并发环境使用的堆 优先队列,用 .put(x) 和 .get() 实现入堆和出堆

最小堆

deque

单线程栈 通过 .append(x) 和 .pop() 实现压栈和出栈FILO

queue.LifoQueue

并发环境使用的栈 通过 .put(x) 和 .get() 实现入栈和出栈

队列

deque

单线程队列 通过 .append(x) 和 .popleft() 实现入队和出队FIFO

两头都可以插入和弹出

队列

queue.Queue

并发环境使用的队列 通过 .put(x) 和 .get() 实现入队和出队

队列

multiprocessing.Queue

多进程环境使用的队列 通过 .put(x) 和 .get() 实现入队和出队

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值