📅  最后修改于: 2020-10-29 01:15:13             🧑  作者: Mango
在本教程中,我们将讨论Queue的基本概念和内置的Queue类,并使用Python代码实现它。
队列是一种线性类型的数据结构,用于顺序存储数据。队列的概念基于FIFO,即“先进先出”。它也被称为“先到先得”。队列的两端位于前端和后端。下一个元素从后端插入,从前端移除。
例如-计算机科学实验室中有20台计算机,并且连接到一台打印机。学生们想print纸;打印机将打印第一个任务,然后print第二个任务,依此类推。如果我们排在最后,我们需要等到所有其他任务都完成之前。
操作系统管理队列以处理计算机内的各种进程。
我们可以在队列中执行以下操作。
Python提供了以下方法,这些方法通常用于在Queue中执行操作。
我们将在以下各节中学习这些功能。
该列表可用作队列,但不适用于性能角度。 Python提供了内置方法insert()和pop()函数来添加和删除元素。列表非常慢,因为如果我们在列表中插入一个新元素,则所有元素都需要移动一个。这需要O(n)时间。因此,建议在队列中使用列表。让我们了解以下如何将列表用作队列的示例。
范例-
que = []
que.append('Apple')
que.append('Mango')
que.append('Papaya')
print(que)
# List is slow!
print(que.pop(0))
输出:
['Apple', 'Mango', 'Papaya']
Apple
说明-
我们在上面的代码中定义了空列表,并使用append()方法插入了一些元素。它将在列表末尾添加一个元素。
我们可以将元素从添加到后端。此过程也称为入队。我们创建一个Queue类,在其中将实现先进先出的概念。让我们了解以下示例。
范例-
class Queue:
def __init__(self):
self.queue = list()
def add_element(self,val):
# Insert method to add element
if val not in self.queue:
self.queue.insert(0,val)
return True
return False
def size(self):
return len(self.queue)
TheQueue = Queue()
TheQueue.add_element("Apple")
TheQueue.add_element("Mango")
TheQueue.add_element("Guava")
TheQueue.add_element("Papaya")
print("The length of Queue: ",TheQueue.size())
输出:
The length of Queue: 4
我们可以从后端移除元素。此过程称为出队。在下面的示例中,我们使用内置的pop()方法从列表中删除一个元素。
范例-
class Queue:
def __init__(self):
self.queue = list()
def add_element(self,val):
# Insert method to add element
if val not in self.queue:
self.queue.insert(0,val)
return True
return False
# Pop method to remove element
def remove_element(self):
if len(self.queue)>0:
return self.queue.pop()
return ("Queue is Empty")
que = Queue()
que.add_element("January")
que.add_element("February")
que.add_element("March")
que.add_element("April")
print(que)
print(que.remove_element())
print(que.remove_element())
输出:
January
February
说明-
在上面的代码中,我们定义了一个名为Queue的类和构造函数。我们为队列变量分配了一个列表构造函数。然后,我们定义了两个方法-add_element()和remove_element()。在add_element()块中,如果该值不在Queue中,则检查条件。如果没有值,则插入元素。
在remove_element()函数块中,我们检查队列是否未下溢的条件。如果返回false,则一一删除该元素。
在以下示例中,我们对队列的元素进行了排序。
范例-
import queue
q = queue.Queue()
q.put(14)
q.put(27)
q.put(11)
q.put(4)
q.put(1)
# Here, we use bubble sort algorithm for sorting
n = q.qsize()
for i in range(n):
# Remove the element
x = q.get()
for j in range(n-1):
# Remove the element
y = q.get()
if x > y :
# put the smaller element at the beginning of the queue
q.put(y)
else:
# the smaller one is put at the start of the queue
q.put(x)
x = y # The greater element is replaced by the x and check again
q.put(x)
while (q.empty() == False):
print(q.queue[0], end = " ")
q.get()
输出:
1 4 11 14 27
Python提供了队列模块以实现多生产者,多消费者队列。队列模块提供了Queue类,该类专门用于线程编程。 Queue类实现所有必需的锁定语义。
我们可以使用内置队列类执行所有操作。
队列模块包含几个类。队列是其中的重要类之一。这在并行计算和多程序设计中非常有用。让我们了解以下队列示例。队列class0uii
范例-
from queue import Queue
que = Queue()
que.put('Apple')
que.put('Mango')
que.put('Papaya')
print(que)
print(que.get())
print(que.get())
print(que.get())
print(que.get_nowait())
print(que.get())
输出:
Apple
Mango
Papaya
Traceback (most recent call last):
File "C:/Users/DEVANSH SHARMA/PycharmProjects/Hello/Queue.py", line 78, in
print(que.get_nowait())
File "C:\Python\lib\queue.py", line 198, in get_nowait
return self.get(block=False)
File "C:\Python\lib\queue.py", line 167, in get
raise Empty
_queue.Empty
collection.deque类用于实现双端队列,该队列支持从两端添加和删除元素。完成过程需要O(1)时间。
双端队列类可以同时在Queue和堆栈中使用,因为它有效地删除和添加了元素。
对于Python标准库中的队列数据结构,collection.deque可能是一个不错的选择。
范例-
from collections import deque
que = deque()
que.append('Apple')
que.append('Mango')
que.append('Banana')
print(que)
deque(['Apple ', 'Mango', 'Banana'])
print(que.popleft())
print(que.popleft())
print(que.popleft())
que.popleft()
输出:
deque(['Apple', 'Mango', 'Banana'])
Apple
Mango
Banana
Traceback (most recent call last):
File "C:/Users/DEVANSH SHARMA/PycharmProjects/Hello/Queue.py", line 101, in
que.popleft()
IndexError: pop from an empty deque
multiprocessing.Queue类用于实现排队的项目,以供多当前工作程序并行处理。 multiprocessing.Queue在进程之间共享数据,并且可以存储任何可腌制的对象。让我们了解以下示例。
范例-
from multiprocessing import Queue
que = Queue()
que.put('Apple')
que.put('Mango')
que.put('Banana')
print(que)
print(que.get())
print(que.get())
print(que.get())
输出:
Apple
Mango
Banana
优先级队列是数据结构中的一种特殊类型的队列。顾名思义,它对元素进行排序,并根据其优先级对元素进行出队。
与普通队列不同,它检索优先级最高的元素,而不是下一个元素。各个元素的优先级由应用于其键的顺序决定。
优先级队列对于处理调度问题最有益,在调度问题中某些任务将基于优先级发生。
例如-操作系统任务是优先级队列的最佳示例-与低优先级任务相比,它执行高优先级(在后台下载更新)。任务计划程序可以允许优先级最高的任务先运行。
有多种方法可以在Python实现优先级队列。让我们了解以下方式。
我们可以使用排序后的Python列表作为优先级队列,以快速识别和删除较小和最大的元素。但是插入新元素很慢,因为它需要O(n)运算。
因此,当在优先级队列中插入的次数很少时,排序列表会很有效。
让我们了解以下示例-
范例-
pri_que = []
pri_que.append((2, 'Apple'))
pri_que.append((1, 'Mango'))
pri_que.append((3, 'Banana'))
# NOTE: Remember to re-sort every time
# a new element is inserted.
pri_que.sort(reverse=True)
while pri_que:
next_item = pri_que.pop()
print(next_item)
输出:
(1, 'Mango')
(2, 'Apple')
(3, 'Banana')
该优先级队列在内部实现了使用heapq并共享相同的时间和空间复杂度。
不同之处在于优先级队列经过协调,并提供锁定语义以支持多个并发事件和使用者。
范例-
from queue import PriorityQueue
q = PriorityQueue()
q.put((2, 'Apple'))
q.put((1, 'Banana'))
q.put((3, 'Mango'))
while not q.empty():
next_item = q.get()
print(next_item)
输出:
(1, 'Banana')
(2, 'Apple')
(3, 'Mango')
我们可以在Python程序中选择任何优先级队列实现,但请记住,queue.PriorityQueue是很好的默认选择。
我们已经讨论了队列的所有基本概念及其实现。它与标准列表类似,但是从性能角度来看总是更好。我们还定义了优先级队列及其各种实现方式。