队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
队列是一种先进先出(First in First Out)的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。
list实现
class Queue():
'''定义队列类'''
def __init__(self):
self.queue = []
def is_empty(self):
return self.queue == []
def put(self,data):
self.queue.append(data)
def get(self):
return self.queue.pop(0)
def peek(self):
return self.queue[0]
def size(self):
return len(self.queue)
if __name__ == '__main__':
queue = Queue()
print('判断队列是否为空:',queue.is_empty())
print('--入队--')
queue.put(10)
queue.put(12)
queue.put(66)
print('--队列大小--',queue.size())
print('--队头元素--',queue.peek())
print('--出队--')
print(queue.get())
print(queue.get())
print(queue.get())
输出结果:
判断队列是否为空: True
--入队--
--队列大小-- 3
--队头元素-- 10
--出队--
10
12
66
链表实现
class Node(object):
def __init__(self,data):
self.data = data
self.next = None
class Queue():
'''定义队列类'''
def __init__(self):
# 实例化时头指针为空
self.head = None
def is_empty(self):
return self.head is None
def put(self,data):
'''入队'''
node = Node(data)
if self.head is None:
# 队列为空时
self.head = node
else:
# 队列不为空时,先将node的指针指向头节点,然后将链表的头指针指向node节点
cur = self.head
while cur.next is not None:
cur = cur.next
cur.next = node
def get(self):
'''出队'''
if self.is_empty():
return None
else:
val = self.head.data
# 将头指针指向头节点的下一个节点
self.head = self.head.next
return val
def peek(self):
'''查看队列头部元素'''
return self.head.data if self.head else None
def size(self):
cur = self.head
count = 0
while cur is not None:
count += 1
cur = cur.next
return count
if __name__ == '__main__':
queue = Queue()
print('判断队列是否为空:',queue.is_empty())
print('--入队--')
queue.put(10)
queue.put(12)
queue.put(66)
print('--队列大小--',queue.size())
print('--队头元素--',queue.peek())
print('--出队--')
print(queue.get())
print(queue.get())
print(queue.get())
print(queue.get())
输出结果:
判断队列是否为空: True
--入队--
--队列大小-- 3
--队头元素-- 10
--出队--
10
12
66
None
Queue和deque
在Python里,queue.Queue主要是为了线程间通信,作为 “队列”只是附带的功能。而collections.deque就是个容器,和dict,list类似。
如果只是想用一个简单的队列,可能从名字上看上去“Queue”更合适。当然用是可以用的,不过,Queue相比deque有个坏处:慢不少。
这里只看最简单的操作,塞东西和取东西。
Queue:put和get
deque:append和popleft
import timeit
from queue import Queue
from collections import deque
def test_queue():
q = Queue()
for i in range(1000):
q.put(i)
for i in range(1000):
q.get()
def test_deque():
q = deque()
for i in range(1000):
q.append(i)
for i in range(1000):
q.popleft()
if __name__ == '__main__':
t_queue = timeit.timeit('test_queue()', setup='from __main__ import test_queue', number=100)
t_deque = timeit.timeit('test_deque()', setup='from __main__ import test_deque', number=100)
print('t_queue', t_queue, 't_deque', t_deque)
print('faster', t_queue / t_deque)
结果如下:
t_queue 0.5356368 t_deque 0.017948600000000203
faster 29.84281782423108
可见,Queue所用的时间,在这里几乎是deque的30倍。
Queue是很高级的同步设施,有例如get_nowait,join等同步用接口,该阻塞就阻塞,该返回就返回。而deque只是个容器。其实从类名也有所反映,Queue是大写的首字母;而deque是和list, dict等一样是小写的首字母。
其他数据结构:栈、队列、树等的实现可以看:python-data-structure