首页 > 编程语言 >数据结构与算法学习笔记 —— 队列(Queue)

数据结构与算法学习笔记 —— 队列(Queue)

时间:2022-09-04 22:56:59浏览次数:64  
标签:打印机 队列 self 打印 Queue 数据结构 def

 

队列 Queue

1. 简介

队列是一种有次序的数据集合 ,其特征是数据项的添加和移除分别发生在该集合的两端:

  - 数据项的添加发生在尾端(rear)

  - 现存数据的移除发生在首端(front)

这种次序安排原则称为(FIFO:first in first out 先进先出

 

例子:

  1. 面向多用户的打印机

  2. 计算机系统中的进程调度

  3. 键盘缓冲

 

ADT数据类型 Queue的python实现(用list来实现queue,index = 0 为rear端, 在这种情况下,enqueu的复杂度为O(n), dequeue的复杂度为O(1) )

class Queue:
    def __init__(self): #创建一个空队列,返回值为Queue对象
        self.items = []

    def enqueue(self,item): # 在队列尾端添加数据项item,无返回值
        self.items.insert(0.item)

    def dequeue(self): # 从队首移除一个数据项,返回修改后的数据项
        return self.items.pop()

    def isEmpty(self): # 判断队列是否为空,返回值为bool型
        return self.items == []

    def size(self): # 返回队列中数据项的个数
        return len(self.items)

 

2. Queue的应用

2.1 热土豆问题

传烫手的热土豆,鼓声听的时候,手里有土豆的小孩要出列(击鼓传花)

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

 

 

 

names = ['Bill','David','Susan','Jane','Joe','Kent']
def passPotato(names,num):
    simQueue = Queue()
    for name in names:
        simQueue.enqueue(name)
    while simQueue.size() > 1:
        for i in range(num):
            simQueue.enqueue(simQueue.dequeue())
        simQueue.dequeue()
    return simQueue.dequeue()
print(passPotato(names, 7))

 

 

 

 

 2.2 打印任务

模拟算法: 打印任务

一个实验室内,在任意一小时内,大约有10名学生在场,这一小时中,没人会发起2次左右的打印,每次1~20页。

打印机的性能 :

草稿模式打印:每分钟10页

正常模式打印:每分钟5页

现在设计一段程序模拟打印的过程,然后对程序运行结果进行分析,以支持打印机模式设定的决策。

 

建模对象:打印机,打印队列,打印任务

打印机属性: 提交时间 打印页数
打印队列属性: 具有FIFO性质的打印任务队列  
打印机的属性: 打印速度 是否忙

 

 

 

 

 

对打印任务的生成进行建模

确定生成概率:20/60*60 = 1/180 # 平均每180秒会有一个task

每个任务的打印页数 1~20,概率相等

 

对打印过程进行建模

打印结束倒计时:新作业开始打印时开始倒计时,回0表示打印完成,可以处理下一个任务

 

模拟时间

同一时间的框架:秒

同步所有过程:在一个时间单位内,对生成打印任务和实施打印时间两个过程各处理一次

 

整个流程的模拟:

1. 创建打印队列对象

2. 时间按照秒的单位流逝

- 按照概率生成打印作业,加入打印队列

- 如果打印机空闲,且队列不空,则取出队首作业打印,记录此作业等待的时间

- 如果打印机忙,则按照打印速度进行1秒打印

- 如果当前作业但因完成,则打印机进入空闲

 

作业的等待时间:

- 生成作业时, 记录生成的时间戳

- 开始打印时, 当前时间减去生成时间即可

 

作业的打印时间:

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

import random

class Printer:
    def __init__(self,ppm):
        self.pagerate = ppm # 打印速度 pages/min
        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)
    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(20):
    simulation(3600,5)

 

标签:打印机,队列,self,打印,Queue,数据结构,def
From: https://www.cnblogs.com/wujiadeqiao/p/16656394.html

相关文章

  • D - path || 2019CCPC网络赛 || 贪心,优先队列,vector
    题意:求无起止点的k短路多组数据,效率约为nlogn解法:由于无起止点,就可以用类似kruskal的贪心思路,优先考虑最短的道路并计数。每使用一个当前最短道路,就入队一个次短道路......
  • 算法提高课 第四章 数据结构之树状数组
    一、介绍功能快速求前缀和O(logn)修改某一个数O(logn)原理c[x]:以x结尾的长度lowbit(x)的所有数的和父节点找所有子节点(求和操作):c[x]=a[x]+c[x-1]+.........
  • 数据结构与算法【Java】05---排序算法总结
    前言数据data结构(structure)是一门研究组织数据方式的学科,有了编程语言也就有了数据结构.学好数据结构才可以编写出更加漂亮,更加有效率的代码。要学习好数据结构就......
  • 江西师范大学865数据结构与程序设计真题答案
    江西师范大学865(863)2018年算法与程序设计题第三题答案3、设二叉树的存储定义同上一题。设计一个算法,判断一个给定的二叉树是否为二叉排序树,设此二叉树中结点的数据值互不......
  • ASP.NET Core源码,数据结构和算法,
    ASP.NETCore源码:https://github.com/dotnet/aspnetcore#ASP.NETCorehttps://github.com/dotnet/runtime#extend扩展库https://github.com/aspnet/KestrelHttpServer ......
  • P2776 [SDOI2007]小组队列题解
    需要解决的问题1.如何将小组中的元素插进去?2.如何按顺序输入。思路显然,这个题的名字就是小组队列,并根据题意及样例,我们可以比较容易的想到队列这个东西。首先......
  • [数据结构10分钟入门] 面向初学者从零实现(基于C语言)-- 单链表
    ​一、链表是什么    链表是一种通过指针串联在一起的线性结构,在内存中是分散存储的(数组在内存中连续分布),链表由一系列节点组成,每个节点都由数据域和指针域组成。主......
  • 消息队列 - 基础篇
    消息队列-基础篇目录消息队列-基础篇前言消息模型消息丢失消息丢失检测消息可靠传递消息重复服务质量标准用幂等性解决消息重复消息积压Producer性能Consumer性能消......
  • 消息队列 day10
    RabbitMQ即一个消息队列,主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分发的作用。消息中间件在互联网公司的使用中越来越多,刚才还看到新闻阿里将Rocket......
  • matlab数据结构之-table2
    table是一种有行和列类似于表的数据结构,每一个都具有易于记忆的标签。表的创建需要有相同长度,且是列的存储方式。使用table()函数创建,以下假设记录病人的姓名、身高和......