数据结构之时间片轮转--队列第二篇

本文介绍了时间片轮转调度算法,并通过Aizu - ALDS1_3_B问题阐述其在队列操作中的应用。文章提供了一个简单的代码实现,展示了如何处理多个任务,每个任务有不同的运行时间。当时间片不足以完成任务时,任务会被移回队尾,继续等待执行。代码使用scanf和printf进行输入输出,适用于处理大规模任务(如n=100000)的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

时间片轮转算法 (Aizu - ALDS1_3_B:Queue)

题意:

There are n processes in a queue. 
Each process has namei and timei. 
The round-robin scheduling handles the processes in order. 
A round-robin scheduler gives each process a quantum (a time slot) and 
interrupts the process if it is not completed by then. 
The process is resumed and moved to the end of the queue, 
then the scheduler handles the next process in the queue.

For example, we have the following queue with the quantum of 100ms.

A(150) - B(80) - C(200) - D(200)
First, process A is handled for 100ms, 
then the process is moved to the end of the queue with the remaining time (50ms).

B(80) - C(200) - D(200) - A(50)
Next, process B is handled for 80ms. 
The process is completed with the time stamp of 180ms and removed from the queue.

C(200) - D(200) - A(50)
Your task is to write a program which simulates the round-robin scheduling .

输入描述:

n q
name1 time1
name2 time2
...
namen timen

In the first line the number of processes n 
and the quantum q are given separated by a single space.

In the following n lines, 
names and times for the n processes are given. 
namei and timei are separated by a single space.

输出描述:

For each process, prints its name and the time the process finished in order.

约束:

1 ≤ n ≤ 100000
1 ≤ q ≤ 1000
1 ≤ timei ≤ 50000
1 ≤ length of namei ≤ 10
1 ≤ Sum of timei ≤ 1000000

输入样例:

5 100
p1 150
p2 80
p3 200
p4 350
p5 20

输出样例:

p2 180
p5 400
p1 450
p3 550
p4 800

这是一道关于时间片轮转调度算法的队列简单使用。

我们有5个任务,已经对应的运行时间:

系统如何处理这些任务呢?

 我们可以看到,我们把任务拍成一队,从左往右依次上工作台运行。

每次我们取队头的一个元素上工作台运行,

工作台每次能运行的时间有限,这个时间即时间片大小,

那么,会造成两种情况:

①时间片>=任务需要的运行时间:

 那么此时运行完之后,这个任务就结束了。

②时间片<任务需要的运行时间:

那么此时我们把任务添加到队尾,然后取下一个元素(队头元素),上工作台:

 这就是时间片轮转算法的大概原理。

前人真是好聪明啊。

用上一篇的队列来写的AC代码:

#include<iostream>
using namespace std;


struct Point//任务结构点 
{
	string name;//任务名称 
	int time;	//运行时间 
};

const int maxn=100000+10;
Point a[maxn];

int head;//头指针
int tail;//尾指针

//进队列
void enqueue(Point x)
{
	a[tail]=x;
	tail=(tail+1)%maxn;
}

//出队列
Point dequeue()
{
	Point x=a[head];
	head=(head+1)%maxn;
	return x;
}

int main()
{
	freopen("in.txt","r",stdin);//重定向,记得去掉
	//输入
	int N,T;
	cin>>N>>T;
	for(int i=0; i<N; i++)
	{
		cin>>a[i].name>>a[i].time;
	}

	//计算与输出
	head=0;//头指针指向第一个元素
	tail=N; //尾指针指向最后一个元素+1的位置
	Point temp;//临时变量,可看成 “工作台 ”上的元素
	int c;//“工作台 ”工作时间
	int sum=0;
	while(head!=tail)
	{
		temp=dequeue();//取队头元素
		c=min(T,temp.time);//根据时间片规则,要么是一个时间片时间,要么是任务时间
		temp.time-=c;
		sum+=c;//计算总时间

		if(temp.time>0)//任务尚未结束,同志还需努力
		{
			enqueue(temp);
		}
		else
		{
			cout<<temp.name<<" "<<sum<<endl;
		}
	}

	return 0;
}

顺带一提的是,根据约束,这里的n达到了100000,所以应该使用 scanf 和 printf 来输入输出,当然由于直接AC了,所以就没有改过来。

运行结果:

Over. 

一、课程设计题目及内容 时间片轮转法实现处理机调度的程序设计提示如下: (1)假设系统有n个进程,每个进程用一个进程控制块(PCB)来代表。进程控制块的格式如下表所示,且参数意义也相同。 进程名 链接指针 到达时间 估计运行时间 进程状态 (2)按照进程到达的先后顺序排成一个循环队列,设一个队首指针指向第一个到达进程的首址。另外再设一个当前运行进程指针,指向当前正运行的进程。 (3)执行处理机调度时,首先选择队首的第一个进程运行。 (4)由于本题目是模拟实验,所以对被选中的进程并不实际启动运行,而只是执行如下操作:1)估计运行时间减1; 2)输出当前运行进程的名字。 用这两个操作来模拟进程的一次运行。 (5)进程运行一次后,以后的调度则将当前指针依次下移一个位置,指向下一个进程,即调整当前运行指针指向该进程的链接指针所指进程,以指示应运行进程,同时还应判断该进程的剩余运行时间是否为0,若不为0,则等待下一轮的运行,若该进程的剩余运行时间为0,则将该进程的状态置为完成状态“C”,并退出循环队列。 (6)若就绪队列不为空,则重复上述的步骤(4)和(5)直到所有进程都运行完为止。 (7)在所设计的调度程序中,应包含显示或打印语句,以便显示或打印每次选中进程的名称及运行一次后队列的变化情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值