• 数据结构之队列(Queue)


    1,队列的定义

      队列:是一种先进先出的数据结构,如下图所示,现进去的数据在队列前面(front),先出队列,后进入队列的数据在后面(rear),后出队列。

            

      队列常用操作:

    q=Queue()      #创建队列
    q.enqueue(item)     # 数据入队列,在队列后面
    q.dequeue()     #数据出队列,从队列前面移出数据并返回
    q.isEmpty()        #返回队列是否为空
    q.size()             #返回队列大小

      操作示例:

            

    2,用python实现队列

        可以用python的list来实现队列,其定义如下面代码所示。 (其中enqueue和dequeue也可以用append和pop(0)来实现)

    class Queue(object):
        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)

    3,队列的应用

      3.1 约瑟夫环问题(Josephus problem)n个人围成一圈,从1开始报数,每当有人报到m时,他被淘汰,下一个人继续从1开始报数,问最后的获胜者是谁?

      Hot potato game:N个人编号1~N,围坐成一个圆圈。从1号人开始传递一个热土豆,经过M次传递后拿着热土豆的人被清除离座,由坐在后面的人拿起热土豆继续进行游戏。最后剩下的人获胜.
      上面两个问题相同,如果M=0和N=5,则游戏人依序被清除,5号游戏人获胜。如果M=1 和N=5,那么被清除的人的顺序是2,4,1,5,最后3号人获胜。

    代码实现如下(n=5,m=7):

    #n个人围成一圈,第一个人从1开始报数,每当有人报到m时,他被淘汰,下一个人继续从1开始报数
    def
    josephus(people_list,num): q = Queue() for people in people_list: q.enqueue(people) while q.size()>1: for i in range(num-1): q.enqueue(q.dequeue()) q.dequeue() return q.dequeue() people_list = [1,2,3,4,5] print josephus(people_list,7)

     (上述代码中people_list = [1,2,3,4,5],加入Queue中后q=[5,4,3,2,1],people_list的正序报数对应q中的倒序报数)

      3.2. 模拟打印机任务队列

        有这样一种情景:有一台打印机,其打印速度可以调节,每分钟打印5页,10页或15页,打印速度越快质量越差。平均每三分钟会有一个学生来打印,打印内容在20页以内,打印机的速度该设置为多少时,才能保证打印质量,同时减少学生的等待时间?

      模拟代码如下:

    #模拟打印机任务队列
    import random
    class Printer(object):
        def __init__(self,ppm):
            self.printrate = ppm   # 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 startTask(self, newTask):
            self.currentTask=newTask
            self.timeRemaining = newTask.getPages()*60/self.printrate
    
    class Task(object):
        def __init__(self,time):
            self.timestamp = time
            self.pages = random.randrange(1,21)
    
        def getPages(self):
            return self.pages
    
        def getStamp(self):
            return self.timestamp
    
        def waitTime(self,currentTime):
            return currentTime-self.timestamp
    
    def simulation(numSeconds,pagesPerMinute):
        printer = Printer(pagesPerMinute)
        printqueue = Queue()
        waitingtime = []
        for currentSecond in range(numSeconds):
            if printTask():
                task = Task(currentSecond)
                printqueue.enqueue(task)
                if (not printer.busy()) and (not printqueue.isEmpty()):
                    newTask = printqueue.dequeue()
                    waitingtime.append(newTask.waitTime(currentSecond))
                    printer.startTask(newTask)
            printer.tick()
        averageWait = sum(waitingtime)/len(waitingtime)
        print "Average wait %6.2f seconds, %d tasks remaining"%(averageWait,printqueue.size())
    
    #平均每三分钟有一个打印任务
    def printTask():
        num = random.randrange(1,181)
        if num==180:
            return True
        else:
            return False
    
    for i in range(10):
        simulation(3600,10)   # 模拟时间60分钟,打印机速度为10

      打印机速度为10,60分钟内模拟结果如下:(平均等待时间158-947秒,剩余2-10个打印任务)

        

    参考:http://interactivepython.org/runestone/static/pythonds/BasicDS/WhatIsaQueue.html

  • 相关阅读:
    Linux基础命令---arch
    JSON漫谈
    django中外键关联表的查询随笔
    <django中render_to_response的可选参数和使用方法>
    有趣的Redis:缓存被我写满了,该怎么办?
    2020全球C++及系统软件技术大会成功落下帷幕
    AWS 宣布创建 Elasticsearch 和 Kibana 分支
    Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate)
    自定义注解!绝对是程序员装逼的利器!!
    Java8 Stream
  • 原文地址:https://www.cnblogs.com/silence-cho/p/10035701.html
Copyright © 2020-2023  润新知