栈:一种后进先出(LIFO)的线性表; push:进栈;pop:出栈; | 队列:一种先进先出(FIFO)的线性表; 每个元素总是从队列的 rear 端进入队列的,然后等待该元素 之前的所有元素都出队之后,当前元素才能出队 | 双端队列(deque):它可以在两端同时进行插入、删除操作 |
Python的queue模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列PriorityQueue。这些队列都实现了锁原语,能够在多线程中直接使用。可以使用队列来实现线程间的同步。
常用方法:
- Queue.qsize() 返回队列的大小
- Queue.empty() 如果队列为空,返回True,反之False
- Queue.full() 如果队列满了,返回True,反之False,Queue.full 与 maxsize 大小对应
- Queue.get([block[, timeout]])获取队列,timeout等待时间
- Queue.get_nowait() 相当于Queue.get(False),非阻塞方法
- Queue.put(item) 写入队列,timeout等待时间
- Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号。每个get()调用得到一个任务,接下来task_done()调用告诉队列该任务已经处理完毕。
- Queue.join() 实际上意味着等到队列为空,再执行别的操作
栈
Python list实现栈
使用 list 列表模拟栈功能的实现方法是,使用 append() 方法存入数据;使用 pop() 方法读取数据。
append() 方法向 list 中存入数据时,每次都在最后面添加数据,pop() 方法默认获取列表最后一个元素。
from queue import LifoQueue
#LIFO即Last in First Out,后进先出。与栈的类似,使用也很简单,maxsize用法同上
lq = LifoQueue(maxsize=0)
#队列写入数据
lq.put(0)
lq.put(1)
lq.put(2)
#输出队列所有数据
print(lq.queue)
#删除队尾数据,并返回该数据
lq.get()
#输出队列所有数据
print(lq.queue)
#输出:
# [0, 1, 2]
# [0, 1]
队列
Python list实现队列
1.使用 list 列表模拟队列功能的实现方法是,定义一个 list 变量,存入数据时使用 insert() 方法,设置其第一个参数为 0,即表示每次都从最前面插入数据;读取数据时,使用 pop() 方法,即将队列的最后一个元素弹出。
2.使用 list 列表模拟队列功能的实现方法是,定义一个 list 变量,存入数据时使用 append() 方法,即表示每次都从最后面插入数据;读取数据时,使用 pop() 方法,设置参数为 0,即将队列的第一个元素弹出。
from queue import Queue
优先队列,级别越低,越优先
from queue import PriorityQueue
# 存储数据时可设置优先级的队列
# 优先级设置数越小等级越高
pq = PriorityQueue(maxsize=0)
#写入队列,设置优先级
pq.put((9,'a'))
pq.put((7,'c'))
pq.put((1,'d'))
#输出队例全部数据
print(pq.queue)
#取队例数据,可以看到,是按优先级取的。
pq.get()
pq.get()
print(pq.queue)
#输出:
[(9, 'a')]
双端队列
# 双端队列
from collections import deque
stack = deque(maxlen=20) #构造最大长度为10的队列
# stack.append('Erlang') #队尾添加元素
for i in range(10):
stack.append(i) #队尾入栈/入队——单个元素
print("队列长度:{},队列:{}".format(len(stack),stack))
for i in range(10):
stack.appendleft(i) #队首入栈/入队——单个元素
print("队列长度:{},队列:{}".format(len(stack),stack))
for i in range(9):
stack.pop() #队尾出栈/出队——单个元素
print("队列长度:{},队列:{}".format(len(stack),stack))
for i in range(7):
stack.popleft() #队首出栈/出队——单个元素
print("队列长度:{},队列:{}".format(len(stack),stack))
stack.reverse() #队列反转
print("队列长度:{},队列:{}".format(len(stack),stack))
stack.extend([5,6]) #队尾入栈/入队——列表、元组
stack.extendleft((7,8)) #队首入栈/入队——列表、元组
print("队列长度:{},队列:{}".format(len(stack),stack))
stack.insert(2,3) #在队列序号为2的位置插入10,其他元素顺序往后移动
# a=stack.index(3) #获取元素在队列中的索引
#print(stack.count(0)) #获取元素在队列中出现的次数
# stack.copy()
# stack.remove(3) #删除队列中的元素
print("队列:old,队列长度:{},队列:{}".format(len(stack),stack))
new_stack=stack.copy() #队列深拷贝
print("队列:new,队列长度:{},队列:{}".format(len(stack),new_stack))
stack.append(1)
print("队列:old,队列长度:{},队列:{}".format(len(stack),stack))
print("队列:new,队列长度:{},队列:{}".format(len(stack),new_stack))
stack.rotate() #执行队列旋转,使收尾相连,队尾元素会被移到队头
print(len(stack))
print("队列:old,队列长度:{},队列:{}".format(len(stack),stack))
print("队列:new,队列长度:{},队列:{}".format(len(stack),new_stack))
# stack.clear() #将队列清空
堆:假设有 n 个数据元素的序列 k0,k1,...,kn-1,当且仅当满足 ki≤k2i+1 且 ki≤k2i+2(其中 i=0,2,...,(n-1)/2)
时,可以将这组数据称为小顶堆(小根堆);或者满足 ki≥k2i+1 且 ki≥k2i+2(其中 i=0,2,...,(n-1)/2)
时,可以将这组数据称为大顶堆(大根堆)。
Python 并没有提供“堆”这种数据类型,它是直接把列表当成堆处理的。Python 提供的 heapq 包中有一些函数,当程序用这些函数来操作列表时,该列表就会表现出“堆”的行为。
- heapify(heap):将堆属性应用到列表上。
- merge(*iterables, key=None, reverse=False):将多个有序的堆合并成一个大的有序堆,然后再输出。
- heappop(heap):将堆中最小元素弹出。
- heappushpop(heap, item):将item 入堆,然后弹出并返回堆中最小的元素。
- heapreplace(heap, x):将堆中最小元素弹出,并将元素x 入堆。
- heappush(heap, item):将 item 元素加入堆。
- nlargest(n, iterable, key=None):返回堆中最大的 n 个元素。
- nsmallest(n, iterable, key=None):返回堆中最小的 n 个元素。