用Python实现队列
- 将LIst首端作为队列的尾端,List末端作为队列的首端。
- enqueue():复杂度为O(n)
- dequeu():复杂度为O(1)
class Queue:
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def enqueue(self, item):
self.items.insert(0,item)
def dequeue(self):
return self.items.pop()
def size(self):
return len(self.items)
q = Queue()
q.enqueue(4)
q.enqueue('dog')
q.enqueue(True)
print(q.size())
print(q.isEmpty())
q.enqueue(8.4)
print(q.dequeue())
print(q.dequeue())
print(q.size())
3
False
4
dog
2
热土豆
- 类似于击鼓传花,传烫手的热土豆,鼓声停的时候,手里有土豆的小孩就要出列。
- 约瑟夫问题:去掉鼓(因为鼓是随机因素),改为传过固定人数。
- 用队列来实现热土豆问题的算法,参加游戏的人名列表,以及传土豆次数num,算法返回最后剩下的人名。
- 模拟程序用队列来存放所有参加游戏的人名,按照传递土豆方向从队首排到队尾。
- 模拟游戏开始,只需要将队首的人出队,随即再到队尾入队,算是土豆的一次传递。
- 传递了num次后,将队首的人移除,不再入队
- 如此反复,直到队列中只剩余1人
class Queue:
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def enqueue(self, item):
self.items.insert(0,item)
def dequeue(self):
return self.items.pop()
def size(self):
return len(self.items)
def hotPotato(namelist, num):
simqueue = Queue()
for name in namelist:
simqueue.enqueue(name)
while simqueue.size() > 1:
for i in range(num):
simqueue.enqueue(simqueue.dequeue())
simqueue.dequeue()
return simqueue.dequeue()
print(hotPotato(["Bill","David","Susan","Jane","Kent","Brad"],7))
Susan
打印任务
- 打印任务:多人共享一台打印机,采取“先到先得”的队列来执行打印任务。
- 打印机系统的容量:能够接收的等待时间内,系统能容纳多少用户以高频率提交多少打印任务。
- 作业的等待时间:生成作业时,记录生成的时间戳;开始打印时,当前时间减去生成时间即可。
- 作业的打印时间:生成作业时,记录作业的页数;开始打印时,页数除以打印速度即可。
- 模拟流程
- 创建打印队列对象
- 对于每一秒(打印过程中的当前秒)
- 是否有新的打印任务生成?如果有,把它加入打印队列,并把当前秒作为其时间戳
- 如果打印机空闲并且有任务正在等待队列中:
- 从打印队列中移除下一个打印任务并且将其提交给打印机
- 从当前秒中减去时间戳,计算得到该任务的等待时间
- 将该任务的等待时间添加到一个列表中,以用于后续操作
- 基于打印任务的页数,求出需要多长的打印时间
- 如果此时打印机正在工作中,则对于打印机而言,就工作了一秒钟;对于打印任务而言,它离打印结束又近了一秒钟(剩余打印时间减1)。
- 如果此时打印任务已经完成,即剩余打印时间为0,打印机就进入空闲状态。
- 时间用尽,开始统计平均等待时间
class Queue:
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def enqueue(self, item):
self.items.insert(0,item)
def dequeue(self):
return self.items.pop()
def size(self):
return len(self.items)
import random
class Printer:
def __init__(self, ppm):
self.pagerate = ppm
self.currentTask = None
self.timeRemaining = 0
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)
def getStamp(self):
return self.timestamp
def getPages(self):
return self.pages
def waitTime(self, currenttime):
return currenttime - self.timestamp
def newPrintTask():
num = random.randrange(1, 181)
if num == 180:
return True
else:
return False
def simulation(numSeconds, pagesPerMinute):
labprinter = Printer(pagesPerMinute)
printQueue = Queue()
waitingtimes = []
for currentSecond in range (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()))
if __name__ == "__main__":
for i in range(10):
simulation(3600, 5)
Average Wait 125.04 secs 1 tasks remaining.
Average Wait 53.55 secs 0 tasks remaining.
Average Wait 97.95 secs 1 tasks remaining.
Average Wait 78.47 secs 0 tasks remaining.
Average Wait 56.47 secs 3 tasks remaining.
Average Wait 77.44 secs 1 tasks remaining.
Average Wait 111.82 secs 0 tasks remaining.
Average Wait 60.53 secs 0 tasks remaining.
Average Wait 11.33 secs 0 tasks remaining.
Average Wait 63.94 secs 0 tasks remaining.