队列 数据结构与算法 python版

什么是队列?

队列是一种有次序的数据集合,其特征是:

新数据项的添加总发生在一端(通常称为“尾 rear”端)

而现存数据项的移除总发生在另一端(通常称为 “首front”端)

当数据项加入队列,首先出现在队尾,随 着队首数据项的移除,它逐渐接近队首。

这种次序安排的原则称为(FIFO:First-in first-out)先进先出 或“先到先服务first-come first-served”

抽象数据类型Queue

Queue():创建一个空队列对象,返回值为 Queue对象;

enqueue(item):将数据项item添加到队尾, 无返回值;

dequeue():从队首移除数据项,返回值为队首 数据项,队列被修改;

isEmpty():测试是否空队列,返回值为布尔值 size():返回队列中数据项的个数。

Python实现ADT Queue

#  Chenyj
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)

采 用 List 来容纳 Queue的数据项 将List首端作为队列 尾端 List的末端作为队列 首端 enqueue()复杂度为 O(n) dequeue()复杂度为 O(1)

 首尾倒过来的实现 ,复杂度也倒过来 

队列的应用:热土豆(约瑟夫问题)

传说犹太人反叛罗马人,落到困境,约瑟夫和39 人决定殉难,坐成一圈儿,报数1~7,报到7的 人由旁边杀死,结果约瑟夫给自己安排了个位置 ,最后活了下来……

用队列来实现热土豆问题的算法,参加游 戏的人名列表,以及传土豆次数num,算 法返回最后剩下的人名

模拟程序采用队列来存放所有参加游戏的人名, 按照传递土豆方向从队首排到队尾 游戏时,队首始终是持有土豆的人

模拟游戏开始,只需要将队首的人出队,随即再 到队尾入队,算是土豆的一次传递 传递了num次后,将队首的人移除,不再入队 如此反复,直到队列中剩余1人

热土豆问题:代码

#  Chenyj
from pythonds.basic.queue import Queue
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秒打印 如果当前作业打印完成,则打印机进入空闲 。时间用尽,开始统计平均等待时间。

作业的等待时间 生成作业时,记录生成的时间戳 开始打印时,当前时间减去生成时间即可。

作业的打印时间 生成作业时,记录作业的页数 开始打印时,页数除以打印速度即可。

#  Chenyj
from pythonds.basic.queue import Queue
import random
class Printer:
    def __init__(self,ppm):
        self.pagerate=ppm   #cyj    打印速度
        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 starNext(self, newtask):    #打印新作业
        self.currentTask=newtask
        self.timeRemaining=newtask.getPages()*60/self.pagerate

 打印任务问题:Python代码2

#  Chenyj
import random

class Task:
    def __init__(self,time):
        self.timestamp=time
        self.pages=random.randrange(1,21)
    def getStamp(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.starNext(nexttask)
        labprinter.tick()
    averageWait=sum(waitingtimes)/len(waitingtimes)
    print('Average Wait %6.2f sec %3d tasks remaining'%(averageWait,printQueue.size()))

为了对打印模式设置进行决策,我们用模 拟程序来评估任务等待时间 通过两种情况模拟仿真结果的分析,我们认识到 如果有那么多学生要拿着打印好的程序源代码赶 去上课的话 那么,必须得牺牲打印质量,提高打印速度。

模拟系统对现实的仿真 在不耗费现实资源的情况下——有时候真实的实验 是无法进行的 可以以不同的设定,反复多次模拟 来帮助我们进行决策。

 

  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值