队列:先进先出(有次序的数据集合)
日常应用:打印机、操作系统中的进程调度、键盘缓冲
Queue():创建一个空队列,返回值为Queue对象;
enqueue(item):将数据项item添加到队尾,无返回值;
dequeue():从队首移除数据项,返回值为队首的数据项,队列被修改;
isEmpty():测试是否空队列,返回值为布尔值;size():返回队列中数据项的个数;
应用
1、热土豆问题(约瑟夫问题)
传递烫手的土豆,鼓声停的时候,手里有土豆的小孩就要出列。
算法:用队列实现,
"""
两个参数,一个名字列表,一个传递次数num,
首先创建一个队列,队首的人始终持有土豆
游戏开始时,队首的人出队,再入队,传递num次,
此时队首的人出队,不再入队,直到队列只有一个人,结束
"""
from pythonds.basic.queue import Queue
def hotPotot(nameList,num):
opQueue = Queue()
for name in nameList:
opQueue.enqueue(name)
while opQueue.size()>1:
for i in range(num):
opQueue.enqueue(opQueue.dequeue())
opQueue.dequeue()
return opQueue.dequeue()
print(hotPotot(["a","s","d","f","h","k","o"],3))
2、 打印机问题
from pythonds.basic.queue import Queue
import random
# 打印机类需要实时监测是否正在执行打印任务
class Printer():
def __init__(self, ppm):
self.pagerate = ppm #页面打印速率
self.currentTask = None #初始化当前任务
self.timeRemaining = 0 #初始化剩余时间
# 计算正在执行的打印任务的剩余时长,即减去当前秒(1秒时长)后的时长
def tick(self):
if self.currentTask != None: #正在执行打印任务
self.timeRemaining = self.timeRemaining - 1 #去除当前秒的任务剩余时长
if self.timeRemaining <= 0: #当前打印任务结束后
self.currentTask = None #在一次任务结束后将打印机设为空闲
# 打印机是否忙碌
def busy(self):
if self.currentTask != None: #当前打印机有任务,则
return True #忙碌
else: #当前打印机无任务,则
return False #空闲
# 进入下一个打印任务
def startNext(self, newtask):
self.currentTask = newtask
self.timeRemaining = newtask.getPages() * 60/self.pagerate #新任务需要的时间秒数
# 一个单独的打印任务
class Task():
def __init__(self,time):
self.timestamp = time #任务被创建和被放入打印队列时的时间节点
self.pages = random.randrange(1,21) #随机生成1-20页的单个任务的打印页数
# 获取时间节点
def getStamp(self):
return self.timestamp
# 获取页数
def getPages(self):
return self.pages
# 用于检索任务开始打印前在队列中的等待时长
def waitTime(self, currenttime):
return currenttime - self.timestamp
# 指定时长、指定打印速率下的打印函数
def simulation(numSeconds, pagesPerMinute):
labprinter = Printer(pagesPerMinute) #实例化打印机类,参数为页/分钟
printQueue = Queue() #创建打印队列
waitingtimes = [] #初始化等待时长列表
for currentSecond in range(numSeconds): #在指定时长numSeconds内的当前秒时
if newPrintTask(): #若有打印任务,则
task = Task(currentSecond) #创建打印任务,并记录当前时间节点
printQueue.enqueue(task) #将该打印任务入队
# 若打印机不忙碌,且打印队列不为空,则
if (not labprinter.busy()) and (not printQueue.isEmpty()):
nexttask = printQueue.dequeue() #出队
waitingtimes.append(nexttask.waitTime(currentSecond)) #将该任务等待时长加入等待列表
labprinter.startNext(nexttask) #打印该任务
labprinter.tick() #计算正在执行的打印任务的剩余时长,并在一次任务结束后将打印机设为空闲
averageWait = sum(waitingtimes) / len(waitingtimes) #平均等待时长
print("Average Wait %6.2f secs %3d tasks remaining." % (averageWait, printQueue.size()))
# 使用随机函数创建打印任务
def newPrintTask():
num = random.randrange(1, 181) #生成随机数,平均3分钟有一个任务
if num == 180:
return True #有打印任务
else:
return False #没有打印任务
if __name__ == '__main__':
for i in range(10): #获取10次打印情况
simulation(3600, 5) #获取1小时内,每分钟打印5张的打印情况
参考:https://blog.csdn.net/qq_38882327/article/details/89308748?
双端队列
特性:可以从两端添加或者删除数据(仍有队首位之分)
1、回文词判定代码
回文词:正读和反读都一样的词
from pythonds.basic.deque import Deque
def word(aString):
charQueue = Deque()
for i in aString:
charQueue.addRear(i)
stillEqual = True
while charQueue.size() > 1 and stillEqual:
first = charQueue.removeFront()
last = charQueue.removeRear()
if first == last:
stillEqual = True
else:
stillEqual = False
return stillEqual
print(word("asdpa"))