队列的实现与应用

抽象数据类型queue的定义

实现了以下数据结构与操作方法的数据类型称为queue

一、队列的python实现
  • 方法一:标准库
from queue import Queue

基于list实现

class Queue():
	def __init__(self):
		self.items = []

	def enqueue(self, item):
		#左边为rear,右边为front;即右边为队首
		#insert(0)操作为O(n)
		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)
二、队列应用
2.1 hot potato问题

from queue import Queue

#热土豆/击鼓传花问题;从0开始数
def hot_potato(players, num):
	q = Queue()
	for player in players:
		q.enqueue(player)

	while q.size() > 1:
		for i in range(num):
			q.enqueue(q.dequeue())
		q.dequeue()

	#循环结束后,只剩下一个player
	return q.dequeue()

if __name__ == '__main__':
	print(hot_potato(["Bill","David","Susan","Jane","Kent","Brad"],7))

2.2模拟打印机平均等待时间

  • 每180秒产生一个打印task
  • 每个task打印1-20页
  • 打印机速率有两种:10页/min,5页/min
  • 求1小时内task的平均等待时间(进入队列到弹出队列)以及未完成的task数目

关键:模拟的本质:for i in range(3600) ,遍历一次代表1秒,而非真正的时间戳

from queue import Queue
from random import randrange

class Printer():
	def __init__(self, pagerate):
		#参数1:当前处理任务剩余秒数;参数2:当前任务对象;参数3:每分钟打印张数
		self.seconds_ramianing = 0
		self.current_task = None
		self.pagerate = pagerate

	def start_task(self,task):
		self.current_task = task
		self.seconds_ramianing = task.get_page()* 60/self.pagerate

	def tick(self):
		#减小一个点数;消耗一秒
		if self.current_task != None:
			self.seconds_ramianing -= 1
			if self.seconds_ramianing == 0:
				self.current_task = None

	def busy(self):
		return self.current_task != None

class Task():
	def __init__(self, current_time):
		self.page = randrange(1,21)
		self.timestamp = current_time

	def wait_time(self,current_time):
		return current_time - self.timestamp

	def get_page(self):
		return self.page

def task_appear():
	#随机发生器,看能否在【1,180】内命中180,命中即判定该秒发生了一个task
	#该函数执行平均180次有一次成功
	num = randrange(1,181)
	return num == 180



def simulation(sum_seconds,pages_per_min):
	#参数1:总的模拟时间;参数2:打印机速率
	printer = Printer(pages_per_min)
	task_queue = Queue()
	wait_times = []
	for i in range(sum_seconds):
		#秒为最小模拟单位
		#模拟task是否产生
		if task_appear():
			newtask = Task(i)
			task_queue.enqueue(newtask)
		#模拟是否提交task队列中的task
		if not printer.busy() and not task_queue.isEmpty():
			current_task = task_queue.dequeue()
			wait_times.append(current_task.wait_time(i))
			printer.start_task(current_task)
		#printer计时也要减小
		printer.tick()

	#计算平均等待时间
	ave_wait_time = sum(wait_times)/len(wait_times)
	print('Average waiting time is {}, and {} tasks remaining!'.format(ave_wait_time,task_queue.size()))

if __name__ == '__main__':
	for i in range(10):
		simulation(3600, 5)
	print('*'*100)
	for i in range(10):
		simulation(3600, 10)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值