队列(Queue)是一系列有顺序的元素的集合,新元素的加入在队列的一端,这一端叫做“队尾” (rear),已有元素的移除发生在队列的另一端,叫做“队首”(front)。当一个元素被加入到队列之 后,它就从队尾开始向队首前进,直到它成为下一个即将被移出队列的元素。最新被加入的元素必须处于队尾,在队列停留最长时间的元素处于队首。这种原则有时候叫做 “先进先出(FIFO)。
本文中,我们使用python实现队列这个数据结构,接续上文所说的列表的特性,我们将使用列表作为队列的主体部分。
因此,我们借助类来实现,初始化为一个空的列表作为队列的主体,并将这个列表的前端作为列的前端,列表的后端作为列的后端。类的定义以及初始化如下:
class Queue:
def __init__(self):
self.items = []
那么对于队列的 入队(enqueue)和出队( dequeue)和获取队伍长度(getlength),根据列表的append函数和pop函数实现,代码如下:
def enqueue(self, val):
return self.items.append(val)
def dequeue(self):
return self.items.pop(0)
def getlength(self):
return len(self.items)
这里有读者可能会有疑问,为什么不使用动态方法,根据经验,动态列表较静态列表的优势和提升并不是很大,除了某些特定场景下会有要求使用到以外,使用场景不是很广,而且静态队列可以满足大部分的要求,并且静态队列简单易学易记,因此掌握静态队列已经可以满足大部分题目的应用场景。
完成代码如下:
class Queue:
def __init__(self):
self.items = []
def enqueue(self, val):
return self.items.append(val)
def dequeue(self):
return self.items.pop(0)
def getlength(self):
return len(self.items)
在学习完以上的内容之后,我们来实战一番,这里引入一个经典的队列例题:热土豆游戏问题。
在这个游戏中,6个孩子围成一个圆圈并以最快的速度接连传递物品,并在游戏的一个特定时刻停止传递,这时手中拿着物 品的小孩就离开圆圈,游戏进行至只剩下一个小孩。
假设我们选择7作为一个循环次数,也就是说,圈中第七个拿到土豆的孩子出圈,一直如此循环下去。在这个问题当中,我们可以发现,这六个小孩可以先排成一列,然后首尾相连以此围成一个圈,也就是一个首尾相接的队列,我们将这种队列叫做循环队列。
在这个问题中,我们使用静态队列来实现这个问题, 在实现的过程中,也可以充分体会到列表操作函数中append和pop函数的便利性。
首先,根据题目要求,我们需要实现:出队、入队、获取队伍长度,代码由上,这里不再赘述,然后,根据题目要求实现循环传递土豆的过程,这里为了方便理解,我们假设土豆一直在队列中的第一个位置,也就是说:假设土豆位置不变而不断改变6个小朋友的位置,使其不断地出队入队一直到以此循环结束,出队一位小朋友,之后一直重复这个操作知到队伍中只剩下最后1位小朋友为止,循环结束。
根据上述内容,实现的代码如下:
def hotPotatoes(namelist,nums):
# 初始化队列
queue = Queue()
# 将小朋友排成一队
for name in namelist:
queue.enqueue(name)
# 开始循环传递土豆
while queue.size() > 1:
for i in range(nums):
queue.enqueue(queue.dequeue())
# 一次传递结束,队首的小朋友手中有土豆,直接出队
queue.dequeue()
# 循环结束,直接返回最后一个小朋友
return queue.dequeue()
这里我们假设有6个小朋友,传递七次后手中有土豆的小朋友出列,则实验部分代码如下:
print(hotPotato(["Bill","David","Susan","Jane","Kent","Brad"],7))
完整的代码如下:
class Queue:
def __init__(self):
self.items = []
def enqueue(self,val):
return self.items.append(val)
def dequeue(self):
return self.items.pop(0)
def size(self):
return len(self.items)
def hotPotatoes(namelist,nums):
queue = Queue()
for name in namelist:
queue.enqueue(name)
while queue.size() > 1:
for i in range(nums):
queue.enqueue(queue.dequeue())
queue.dequeue()
return queue.dequeue()
print(hotPotato(["Bill","David","Susan","Jane","Kent","Brad"],7))
最终的输出结果:
以上就是本文的全部内容,如有大佬发现错误或更好的意见,欢迎评论区交流!