Python 中的队列
队列是一种遵循先进先出(FIFO)原则的线性数据结构。
队列
可以将队列想象成人们在超市里排队。
第一个排队的人也是第一个可以付款并离开超市的人。
我们可以在队列上执行的基本操作包括:
- 入队(Enqueue):向队列中添加一个新元素。
- 出队(Dequeue):从队列中移除并返回第一个(队首)元素。
- 查看队首元素(Peek):返回队列中的第一个元素。
- 判断队列是否为空(isEmpty):检查队列是否为空。
- 队列大小(Size):找出队列中的元素数量。
队列可以通过数组或链表来实现。
队列可用于实现办公室打印机的作业调度、电子票务的订单处理,或创建图中的广度优先搜索算法。
队列经常与栈一起提及,栈是上一页描述的一种类似的数据结构。
使用 Python 列表实现队列
对于 Python 列表(和数组)而言,队列的外观和行为可以如下所示:
添加: 移除:
由于 Python 列表对实现队列所需的功能提供了良好的支持,因此我们可以从创建队列开始,并仅用几行代码就能执行队列操作:
实例
使用 Python 列表作为队列:
queue = []
# 入队
queue.append('A')
queue.append('B')
queue.append('C')
print("Queue: ", queue)
# 查看队首元素
frontElement = queue[0]
print("Peek: ", frontElement)
# 出队
poppedElement = queue.pop(0)
print("Dequeue: ", poppedElement)
print("Queue after Dequeue: ", queue)
# 判断队列是否为空
isEmpty = not bool(queue)
print("isEmpty: ", isEmpty)
# 队列大小
print("Size: ", len(queue))
注意:虽然使用列表很简单,但从列表开头移除元素(出队操作)需要移动所有剩余元素,这使得对于大型队列来说效率较低。
实现队列类
以下是队列类的完整实现:
实例
使用 Python 类作为队列:
class Queue:
def __init__(self):
self.queue = []
def enqueue(self, element):
self.queue.append(element)
def dequeue(self):
if self.isEmpty():
return "Queue is empty"
return self.queue.pop(0)
def peek(self):
if self.isEmpty():
return "Queue is empty"
return self.queue[0]
def isEmpty(self):
return len(self.queue) == 0
def size(self):
return len(self.queue)
# 创建一个队列
myQueue = Queue()
myQueue.enqueue('A')
myQueue.enqueue('B')
myQueue.enqueue('C')
print("Queue: ", myQueue.queue)
print("Peek: ", myQueue.peek())
print("Dequeue: ", myQueue.dequeue())
print("Queue after Dequeue: ", myQueue.queue)
print("isEmpty: ", myQueue.isEmpty())
print("Size: ", myQueue.size())
使用链表实现队列
链表由包含某种数据的节点以及指向下一个节点的指针组成。
使用链表的一个主要好处是,节点可以存储在内存中的任何空闲位置,不像数组中的元素那样必须连续存储。链表的另一个优点是,在添加或删除节点时,列表中的其他节点不需要移动。
为了更好地理解使用数组或链表实现队列的优缺点,你应该查看这个页面,它解释了数组和链表在内存中的存储方式。
以下是使用链表实现队列的方法:
实例
使用链表创建队列:
class Node:
def __init__(self, data):
self.data = data
self.next = None
class Queue:
def __init__(self):
self.front = None
self.rear = None
self.length = 0
def enqueue(self, element):
new_node = Node(element)
if self.rear is None:
self.front = self.rear = new_node
self.length += 1
return
self.rear.next = new_node
self.rear = new_node
self.length += 1
def dequeue(self):
if self.isEmpty():
return "Queue is empty"
def isEmpty(self):
return self.length == 0
def size(self):
return self.length
def printQueue(self):
temp = self.front
while temp:
print(temp.data, end=" ")
temp = temp.next
print()
def dequeue(self):
if self.isEmpty():
return "Queue is empty"
temp = self.front
self.front = temp.next
self.length -= 1
if self.front is None:
self.rear = None
return temp.data
def peek(self):
if self.isEmpty():
return "Queue is empty"
return self.front.data
def isEmpty(self):
return self.length == 0
def size(self):
return self.length
def printQueue(self):
temp = self.front
while temp:
print(temp.data, end=" -> ")
temp = temp.next
print()
# 创建一个队列
myQueue = Queue()
myQueue.enqueue('A')
myQueue.enqueue('B')
myQueue.enqueue('C')
print("Queue: ", end="")
myQueue.printQueue()
print("Peek: ", myQueue.peek())
print("Dequeue: ", myQueue.dequeue())
print("Queue after Dequeue: ", end="")
myQueue.printQueue()
print("isEmpty: ", myQueue.isEmpty())
print("Size: ", myQueue.size())
使用链表实现队列的原因:
- 动态大小:与数组不同,队列可以动态地增长和缩小。
- 无需移动:队列的队首元素可以移除(出队)而无需移动内存中的其他元素。
不使用链表实现队列的原因:
- 额外内存:每个队列元素必须包含指向下一个元素的地址(即下一个链表节点)。
- 可读性:对于某些人来说,代码可能更难阅读和编写,因为它更长且更复杂。
队列的常见应用
队列在许多现实场景中都有应用:
- 操作系统中的任务调度
- 图中的广度优先搜索
- 分布式系统中的消息队列