实验指南
运行环境:
Dev c++
算法思想:
短进程优先 (SPF)调度算法则是从就绪队列中选出一个估计运行时间最短的进程,将处理机分配给它,使它立即执行并一直执行到完成
核心数据结构:
typedef struct data{
int hour;
int min;
}time;
typedef struct node{
int id;//编号
char name[20];//名字
time arrive;//到达时间
int zx;//执行时间;
time start;//开始时间
time finish;//完成时间
int zz;//周转时间=执行完成时间-到达就绪队列时间
double zzxs;//带权周转时间=周转时间/执行时间
struct node* next;
}linknode;
typedef linknode* linklist;
typedef struct{
linklist front;
linklist rear;
}queue; //队列
程序主体框架:
//函数名:init 参数:无
queue* init(){
//函数功能:初始化队列,返回队列指针
}
//函数名:insert 参数:Queue *cc, node *x
void insert(queue* cc,linklist s){
//函数功能:尾插入队
}
//函数名:dele 参数:Queue *cc
void dele(queue* cc){
//功能:队首结点出队
}
//函数名:input 参数:Queue *cc
void input(queue* cc){
//功能:实现作业队列的输入
}
//函数名:sort参数:Queue *cc
void sort(queue* cc){
//函数功能:对到达时间进行排序
}
//函数名:solve_SJF参数:Queue *cc
void solve_SJF(queue* cc){
//函数功能:解决短进程优先调度算法
}
int main()
{
while(true)
{
int op;
printf("请输入操作(1:开始进程调度;0:结束进程)");
scanf("%d",&op);
if(op==0) break;
queue *cc;
cc = init(cc);
input(cc);
solve_SJF(cc);
}
return 0;
}
测试用例:
用例一:
5001 p1 9:40 20
5004 p4 10:10 10
5005 p5 10:05 30
5002 p2 9:55 15
5003 p3 9:45 25用例二:
5001 p1 19:40 20
5002 p4 10:10 10
5003 p5 10:05 30
5004 p2 9:55 15
5005 p3 9:45 25
5006 p6 11:40 20
5007 p8 12:10 10
5008 p9 13:05 30
5009 p10 19:55 15
5010 p7 7:15 15
关键代码
#include <iostream>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
typedef struct data{
int hour;
int min;
}time;
typedef struct node{
int id;//编号
char name[20];//名字
time arrive;//到达时间
int zx;//执行时间;
time start;//开始时间
time finish;//完成时间
int zz;//周转时间=执行完成时间-到达就绪队列时间
double zzxs;//带权周转时间=周转时间/执行时间
struct node* next;
}linknode;
typedef linknode* linklist;
typedef struct{
linklist front;
linklist rear;
}queue; //队列
void sort(queue* cc);
void solve_SJF(queue* cc);
//函数名:init 参数:无
queue* init(){
//函数功能:初始化队列,返回队列指针
queue* p=(queue*)malloc(sizeof(queue));
p->front=NULL;
p->rear=NULL;
return p;
}
//函数名:insert 参数:Queue *cc, node *x
void insert(queue* cc,linklist s){
//函数功能:尾插入队
linknode*p=(linknode *)malloc(sizeof(linknode));
*p=*s;
//printf("%d ",p->id);
if(cc->front==NULL&&cc->rear==NULL)
{
cc->front=p;
cc->rear=p;
}
else
{
cc->rear->next=p;
cc->rear=p;
}
}
//函数名:dele 参数:Queue *cc
void dele(queue* cc){
//功能:队首结点出队
linklist bl,p;
float zz=0,zx=0;
int n=0;
bl=cc->front;
printf("模拟短进程优先调度过程输出结果\nid号 名字 到达时间 执行时间(分钟) 开始时间 完成时间 周转时间(分钟) 带权周转系数\n");
while(bl!=NULL)
{
printf("%d\t%s\t%d:%02d\t\t%d\t\t%d:%02d\t%d:%02d\t\t%d\t\t%.2f\n",bl->id,bl->name,bl->arrive.hour,bl->arrive.min,bl->zx,bl->start.hour,bl->start.min,bl->finish.hour,bl->finish.min,bl->zz,bl->zzxs);
p=bl;
zz=zz+bl->zz;
zx=zx+bl->zzxs;
bl=bl->next;
free(p);
n++;
}
printf("系统平均周转时间为:\t\t\t\t\t\t\t%.2f\n",zz/n);
printf("系统平均带权周转系数为:\t\t\t\t\t\t\t\t%.2f\n",zx/n);
}
//函数名:input 参数:Queue *cc
void input(queue* cc){
//功能:实现作业队列的输入
int n;
linklist head=NULL,q;
printf("请输入进程数:");
scanf("%d",&n);
while(n--)
{
linknode*p=(linknode *)malloc(sizeof(linknode));
scanf("%d %s %d:%d %d",&p->id,&p->name,&p->arrive.hour,&p->arrive.min,&p->zx);
p->next=NULL;
insert(cc,p);
}
head=cc->front;
sort(cc);
}
//函数名:sort参数:Queue *cc
void sort(queue* cc){
//函数功能:对到达时间进行排序
linklist head=NULL,bl,pre,q;
bl=cc->front;
while(bl!=NULL)
{
linknode*p=(linknode *)malloc(sizeof(linknode));
*p=*bl;
p->next=NULL;
if(head==NULL)
{
head=p;
}
else
{
pre=NULL;
q=head;
while(q!=NULL)
{
if((p->arrive.hour<head->arrive.hour)||((p->arrive.hour==head->arrive.hour)&&(p->arrive.min<head->arrive.min)))
{
p->next=head;
head=p;
break;
}
else if(((p->arrive.hour>q->arrive.hour)||((p->arrive.hour==q->arrive.hour)&&(p->arrive.min>q->arrive.min)))&&q->next==NULL)
{
q->next=p;
break;
}
else if((p->arrive.hour<q->arrive.hour)||((p->arrive.hour==q->arrive.hour)&&(p->arrive.min<q->arrive.min)))
{
p->next=q;
pre->next=p;
break;
}
pre=q;
q=q->next;
}
}
bl=bl->next;
}
cc->front=head;
cc->rear=pre;
}
//函数名:solve_SJF参数:Queue *cc
void solve_SJF(queue* cc){
//函数功能:解决短进程优先调度算法
sort(cc);
linklist head=NULL,min,pre,q,bl,bl2,bl3,sf;
time tt;
bl=cc->front;
while(bl!=NULL)
{
if(head==NULL)
{
//printf("创建链表为空\n");
linknode*p=(linknode *)malloc(sizeof(linknode));
*p=*bl;
p->next=NULL;
p->start.hour=p->arrive.hour;
p->start.min=p->arrive.min;
p->finish.min=(p->start.min+p->zx)%60;
p->finish.hour=p->start.hour+(p->start.min+p->zx)/60;
p->zz=p->finish.hour*60+p->finish.min-p->arrive.hour*60-p->arrive.min;
p->zzxs=p->zz*1.0/p->zx;
head=p;
q=head;
tt.min=(p->arrive.min+p->zx)%60;
tt.hour=p->arrive.hour+(p->arrive.min+p->zx)/60;
bl=bl->next;
}
else
{
//printf("创建链表不为空\n");
bl2=bl;
min=bl;
bl3=bl;
int flag=0;
while(bl2!=NULL)
{
if((bl2->arrive.hour<tt.hour)||((bl2->arrive.hour==tt.hour)&&(bl2->arrive.min<tt.min)))
{
if(bl2->zx<min->zx)
{
min=bl2;
flag=1;
while(1)
{
if(bl3->next==min||bl3==min)
break;
bl3=bl3->next;
}
}
}
bl2=bl2->next;
}
if(flag==1)
{
//printf("找到最小执行时间\n");
linknode*p=(linknode *)malloc(sizeof(linknode));
*p=*min;
p->next=NULL;
q->next=p;
q=p;
bl3->next=min->next;
free(min);
p->start.hour=tt.hour;
p->start.min=tt.min;
p->finish.min=(tt.min+p->zx)%60;
p->finish.hour=tt.hour+(tt.min+p->zx)/60;
p->zz=p->finish.hour*60+p->finish.min-p->arrive.hour*60-p->arrive.min;
p->zzxs=p->zz*1.0/p->zx;
tt.min=p->finish.min;
tt.hour=p->finish.hour;
}
else
{
//printf("没有找到最小执行时间\n");
linknode*p=(linknode *)malloc(sizeof(linknode));
*p=*min;
p->next=NULL;
if((p->arrive.hour<tt.hour)||((p->arrive.hour==tt.hour)&&(p->arrive.min<tt.min)))
{
p->start.hour=tt.hour;
p->start.min=tt.min;
p->finish.min=(tt.min+p->zx)%60;
p->finish.hour=tt.hour+(tt.min+p->zx)/60;
p->zz=p->finish.hour*60+p->finish.min-p->arrive.hour*60-p->arrive.min;
p->zzxs=p->zz*1.0/p->zx;
tt.min=p->finish.min;
tt.hour=p->finish.hour;
}
else
{
p->start.hour=p->arrive.hour;
p->start.min=p->arrive.min;
p->finish.min=(p->start.min+p->zx)%60;
p->finish.hour=p->start.hour+(p->start.min+p->zx)/60;
p->zz=p->finish.hour*60+p->finish.min-p->arrive.hour*60-p->arrive.min;
p->zzxs=p->zz*1.0/p->zx;
tt.min=p->finish.min;
tt.hour=p->finish.hour;
}
q->next=p;
q=p;
bl=bl->next;
}
}
}
cc->front=head;
bl=head;
while(bl->next!=NULL)
{
bl=bl->next;
}
cc->rear=bl;
dele(cc);
}
int main()
{
while(true)
{
int op;
printf("请输入操作(1:开始进程调度;0:结束进程)");
scanf("%d",&op);
if(op==0) break;
queue *cc;
cc = init();
input(cc);
solve_SJF(cc);
}
return 0;
}
运行结果
实验总结
①经过前两次的实验后,对单链表的使用相较之前熟练了很多,但有时对指针的应用还不是很熟练,要多加练习
②在这次的实验中,对多种情况的分析没有做得很好,导致一直停留在if-else语句处,今后考虑问题要从多个方面来考虑