基于python的数据结构与算法(北京大学)课程中的代码实现(队列部分)
2020-07-07 21:47
756 查看
-
什么是队列(Queue)?
队列是一种有次序的数据集合,其特征是,新数据项的添加总发生在一端(通常称为"尾(rear)"端);
而现存数据项的移除总发生在另一端(通常称为”首(front)“端)
当数据项加入队列,首先出现在队尾,随着首数据项的移除,它逐渐接近队首。
新加入的数据项必须在数据集末尾等待。这种次序安排的原则称为 先进先出(FIFO:first in first out)或 先到先服务(first-come first-served) -
队列的应用:
-
队列的基本操作:
queue() 创建一个空队列对象,返回值为queue对象
enqueue(item) 将数据项item添加到队尾,无返回值
dequeue() 从队首移除数据项,返回值为队首数据项,队列被修改
isEmpty() 测试是否为空队列,返回值为布尔型
size() 返回队列中数据项的个数例如:
-
python实现队列
class Queue(): def __init__(self): self.queque = [] def enqueue(self,item): self.queue.append(item) def dequeue(self): return self.queue.pop(0) def isEmpty(self): return self.queque == [] def size(self): return len(self.queque)
标准代码选择将列表头当作队尾,列表尾当作队首。让enqueue()的复杂度为O(n),dequeue的复杂度为O(1)。
标准代码如下:
class Queue(): def __init__(self): self.items = [] def enqueue(self,item): self.items.insert(0,item) def dequeue(self): return self.items.pop() def isEmpty(self): return self.items == [] def size(self): return len(self.items)
- 队列解决热土豆问题(约瑟夫问题)
什么是热土豆问题:
类似“击鼓传花”问题,但将“击鼓”的过程设置为传递固定人数。
算法思路:
1.用队列来实现热土豆问题的算法,参加游戏的人名列表,以及传土豆次数num,算法返回最后剩下的人名。
2.采用队列存放参加游戏的人名,按照传递土豆方向从队首排到队尾,游戏时,队首始终是持有土豆的人。
3.游戏开始,只需要将队首的人出队,随即再到队尾入队,算是土豆的一次传递,传递了num次后,将队首的人移除,不再入队,如此反复,直到队里剩余1个人。
def HotPotato(namelist,num): Q = Queue() for name in namelist: Q.enqueue(name) while Q.size() > 1: for i in range(num): temp = Q.dequeue() Q.enqueue(temp) Q.dequeue() return namelist[0] print(HotPotato(['A','B','C','D','E','F'],4))
自写代码不够简洁,引入了一个可以忽略的变量temp,来进行出队入队时的存储,标准代码为:
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()
- 队列模拟打印任务:
打印任务具体实例配置如下:一个实验室,在任意的一个小时内,大约有10名学生在场,这一小时中,每人会发起两次打印任务,每次1-20页。
打印机的性能是:以草稿模式打印的话,每分钟10页;以正常模式打印的话,打印质量好,但速度下降为每分钟5页。
决策支持:找到一个让大家都不会等太久,又能尽量提高打印质量。
问题建模:
对象:打印任务、打印队列、打印机 打印任务的属性:提交时间,打印页数 打印队列的属性:具有FIFO性质的打印任务队列 打印机的属性:打印速度,是否在忙 过程:生成和提交打印任务: 确定生成概率:每180秒会有一个作业生成并提交,概率为每秒1/180 确定打印页数:实例是1-20页,也就是1-20页之间概率相同 过程:实施打印: 当前打印就是正在打印的作业 新作业开始打印时开始倒计时,回0表示打印完毕,可以处理下一个作业 模拟时间: 统一的时间框架:以秒均匀流逝的时间,设定结束时间 同步所有过程:在一个时间单位里,对生成打印任务和实施打印两个过程各处理一次
模拟流程:
创建打印队列对象。 时间按照秒的单位流逝。按照概率生成打印作业,加入打印队列;如果打印机空闲且队列不空,则取出队首作业打印,记录此作业等待时间;如果打印机忙,则按照打印速度进行1秒打印;如果当前作业打印完成,则打印机进入空闲。 时间用尽,开始统计平均等待时间。
class Printer: def __init__(self,ppm): self.pagerate = ppm # 打印速度 self.currentTask = None # 打印任务 self.timeRemaining = 0 # 任务倒计时 def tick(self): # 打印1秒 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) # 1/180概率生成作业 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())) for i in range(10): simulation(3600,10)
相关文章推荐
- C++类模板 实现队列的链式存储结构算法 《数据结构》(北京科海) 部分代码摘抄,自己编写运行
- Python数据结构之栈、队列的实现代码分享
- 用Python实现的数据结构与算法:队列
- 数据结构(基于python实现)02-算法复杂度分析
- python算法与数据结构-二叉树的代码实现(46)
- [算法和数据结构入门][Day3]用最少的代码行数实现python 直接替换列表中的元素几种方法
- 利用python的双向队列(Deque)数据结构实现回文检测的算法
- [算法和数据结构入门]用Python的数组实现一个队列的作用
- 用Python实现的数据结构与算法:队列
- Python实现的数据结构与算法之双端队列详解
- 算法与数据结构-栈与队列 讲解与java代码实现
- 数据结构C语言实现之链式队列的6种算法代码
- C++类模板 实现循环队列的顺序存储结构算法 《数据结构》(北京科海) 部分摘抄 自己编写实现
- Python全栈(二)数据结构和算法之6.队列的实现和冒泡排序的实现
- 【数据结构&&算法系列】插入排序简单介绍及python代码
- 基于python写的专门用于字符串匹配的smartscript实现代码
- 优先级队列(代码实现+部分练习)
- SPFA 算法的学习--基于Bellman-Ford算法的一种队列实现
- 数据挖掘之Apriori算法详解和Python实现代码分享
- 算法与数据结构课程中的c++实现的顺序表和链表