#include <stdio.h>
#include <stdlib.h>
int* Bubble(int up[],int n)//冒泡排序算法
{
int i,j;
int temp=0;
for(i=0;i<=n;++i)
{
for(j=i;j<=n;++j)
{
if(up[i]>up[j])
{
temp=up[i];
up[i]=up[j];
up[j]=temp;
}
}
}
return up;
}
void output(int up[],int i,int head)//输出函数
{
int n;
up=Bubble(up,i);
printf(" 需要寻找的磁道号:\n");
printf("+");
for(n=0;n<=i+1;n++)
printf("-----+");
printf("\n");
printf("|head |");
for(n=0;n<=i;n++)
{
printf(" %-2d号|",n+1);//输出需要寻找磁道号
}
printf("\n");
printf("+");
for(n=0;n<=i+1;n++)
printf("-----+");
printf("\n");
printf("|");
printf(" %-4d|",head);
for(n=0;n<=i;n++)
{
printf(" %-4d|",up[n]);//输出需要寻找磁道号
}
printf("\n");
printf("+");
for(n=0;n<=i+1;n++)
printf("-----+");
printf("\n");
}
int AutoSetDI(int DiscL[], int head,int Limit)//随机生成磁道数
{
int n;
printf("请输入随机生成磁道数个数:");
scanf(" %d",&n);
int i;
for(i=0;i<=n-1;i++)
{
DiscL[i]=rand()%Limit;//随机生成n个磁道号
}
i--;
output(DiscL,i,head);
return i;
}
int SetDI(int DiscL[],int head,int Limit)//手动输入磁道数
{
int i;
int d;
char c;
printf("请输入需要寻找的磁道号:");
for(i=0;i<100;i++)
{
scanf("%d",&d);
if(d>=0&&d<=Limit)
DiscL[i]=d;
else {
fflush(stdin);
printf("输入范围请勿超过0至%d \n",Limit);
i=SetDI(DiscL,head,Limit);
return i;
}
scanf("%c",&c);
if(c=='\n')
break;
if(i==99)
break;
}
output(DiscL,i,head);
return i;
}
void form(int DiscLine[],int i,int n)//制表函数
{
int j,k;
printf("|");
printf(" %-4d|",DiscLine[i]);
for(j=0;j<=n;j++)
{
if(j==i)
printf(" * |");
else printf(" |");
}
printf("\n");
printf("+");
for(k=0;k<=n+1;k++)
printf("-----+");
printf("\n");
}
void SSTF(int head,int DiscLine[],int n) //最短寻道时间优先算法(SSTF)
{
int i,j,k,sum=0;
if(DiscLine[n]<=head)//当前磁头位置大于最外围欲访问磁道
{
for(i=n;i>=0;i--)
{
form(DiscLine,i,n);
}
sum=head-DiscLine[0];
}
else
if(DiscLine[0]>=head)//当前磁头位置小于最里欲访问磁道
{
for(i=0;i<=n;i++)
{
form(DiscLine,i,n);
}
sum=DiscLine[n]-head;
}
else
{
for(k=1;DiscLine[k]<head;k++);//确定当前磁道在已排序列的位置
i=k-1;
j=k;
while((i>=0)&&(j<=n))
{
if(head-DiscLine[i]<=(DiscLine[j]-head))//选择距离磁头近的磁道
{
form(DiscLine,i,n);
sum+=head-DiscLine[i];
head=DiscLine[i];
i=i-1;
}
else
{
form(DiscLine,j,n);
sum+=DiscLine[j]-head;
head=DiscLine[j];
j=j+1;
}
}
if(i==-1)//磁头位置里侧的磁道已访问完
{
for(;j<=n;j++)
form(DiscLine,j,n);
sum+=DiscLine[n]-DiscLine[0];
}
else if(j==n+1)//磁头位置外侧的磁道已访问完
{
for(;i>=0;i--)
form(DiscLine,i,n);
sum+=DiscLine[n]-DiscLine[0];
}
printf("\n 移动磁道数:<%5d> \n",sum);
printf(" 平均寻道长度:<%0.2f> \n",sum/(n+1.0));
}
}
void SCAN(int head,int DiscLine[],int n)//电梯算法(SCAN)
{
int i,j,k,sum=0,x;
if(DiscLine[n]<=head)//当前磁头位置大于最外围欲访问磁道
{
for(i=n;i>=0;i--)
{
form(DiscLine,i,n);
}
sum=head-DiscLine[0];
}
else
if(DiscLine[0]>=head)//当前磁头位置小于最里欲访问磁道
{
for(i=0;i<=n;i++)
{
form(DiscLine,i,n);
}
sum=DiscLine[n]-head;
}
else //磁头位置在最里侧磁道与最外侧磁道之间
{
for(k=0;DiscLine[k]<head;k++);//确定当前磁道在已排序列的位置
i=k-1;
j=k;
printf("\n请输入磁头移动的方向 (0 表示向内 ,1表示向外) : ");
scanf("%d",&x); //确定磁头访问的方向
output(DiscLine,n,head);
if(x==0||x==1)
{
if(x==0)//向内
{
for(;i>=0;i--)
form(DiscLine,i,n);
for(;j<=n;j++)
form(DiscLine,j,n);
sum=head-2*DiscLine[0]+DiscLine[n];
}
if(x==1)//向外
{
for(;j<=n;j++)
form(DiscLine,j,n);
for(;i>=0;i--)
form(DiscLine,i,n);
sum=2*DiscLine[n]-head-DiscLine[0];
}
}
else
{
fflush(stdin);
printf("请重新输入");
SCAN(head,DiscLine,n);
exit(0);
}
}
printf("\n 移动磁道数:<%5d> \n",sum);
printf(" 平均寻道长度:<%0.2f> \n",sum/(n+1.0));
}
int main()
{
int i;//需要访问的磁道号数组尾号
int head;
int limit;
int n;
printf("请输入最大磁道号:");
scanf("%d",&limit);
printf("请输入初始的磁头位置:");
scanf("%d",&head);
int DiscLine[100];
int n1,n2;
printf(" ╭================================╮ \n");
printf(" || 请输入你选择的算法 || \n");
printf(" || 1.最短寻道时间优先算法(SSTF) || \n");
printf(" || 2.电梯调度算法(scan) || \n");
printf(" || 0.退出程序 || \n");
printf(" ╰=================================╯ \n");
scanf(" %d",&n1);
if(n1==0) exit(0);
printf(" ╭=======================╮ \n");
printf(" || 请输入生成磁道数方式 || \n");
printf(" || 1.随机生成磁道数 || \n");
printf(" || 2.手动输入磁道数 || \n");
printf(" || 0.退出程序 || \n");
printf(" ╰=======================╯ \n");
scanf(" %d",&n2);
if(n2==0) exit(0);
switch(n2)
{
case 1:
i=AutoSetDI(DiscLine,head,limit); //随机生成磁道数
break;
case 2:
i=SetDI(DiscLine,head,limit); //手动输入磁道数
break;
}
switch(n1)
{
case 1:
SSTF(head,DiscLine,i); //最短寻道时间优先算法(SSTF)
break;
case 2:
SCAN(head,DiscLine,i); //扫描算法(SCAN)
break;
}
printf(" ╭==================╮ \n");
printf(" || 按任意键继续程序|| \n");
printf(" || 按0退出程序 || \n");
printf(" ╰==================╯ \n");
scanf("%d",&n);
if(n!=0)
{
main();
}
return 0;
}
磁盘调度算法的模拟(C语言)
于 2021-10-27 10:15:26 首次发布