使用C语言编写操作系统磁盘调度算法,代码
/*
* Author : tanchang
* Text : GoodGood学习,天天UPUP
*/
#include <stdio.h>
#include <cstdlib>
#include <ctime>
#define MAX_SEHCDULE 100
#define MAX_DISK 1000
int nums; //定义调度数量
int init; //定义初始磁道位置
struct DiskRequest {
int num;
int check;
};
void check_disk(int num, DiskRequest Sehcdule[MAX_SEHCDULE]);
void check_init(DiskRequest Sehcdule[MAX_SEHCDULE]);
void FCSF(DiskRequest Sehcdule[MAX_SEHCDULE]);
void SSTF(DiskRequest Sehcdule[MAX_SEHCDULE]);
int compute_num(int i, DiskRequest Sehcdule[MAX_SEHCDULE]);
void SCAN(DiskRequest Sehcdule[MAX_SEHCDULE]);
void CSCAN(DiskRequest CSCAN_STACK[MAX_SEHCDULE]);
char check_input_yn();
int main() {
// int Disk[MAX_DISK];
while (true) {
while (true){
printf("请输入你的磁盘请求数量:");
scanf("%d",&nums);
if (nums >= 0 && nums <= MAX_SEHCDULE) {
break;
} else {
printf("输入磁盘请求数量不在范围内!!请重新输入:\n");
continue;
}
}
DiskRequest Sehcdule[nums];
check_disk(nums, Sehcdule); //判读输入磁盘请求数量是否合理,合理就随机分配
while (true){
printf("请输入你的初始磁道位置:");
scanf("%d", &init);
if (init >= 0 && init <= MAX_DISK ){
break;
} else {
printf("输入磁盘数量不在磁道内!!请重新输入:");
continue;
}
}
check_init(Sehcdule);
char cont;
printf("是否重新输入数值?(y/n):");
//判断输入是否正确
//判断输入是否输入正确
cont = check_input_yn();
if (cont == 'y') {
continue;
} else if (cont == 'n') {
break;
}
}
}
//先判断是输入的调度数量,在根据输入的数字来随机生成队列数
void check_disk(int nums,DiskRequest Sehcdule[MAX_SEHCDULE]) {
printf("初始化的磁盘调度队列为:\n");
srand((unsigned)time(NULL));
for (int i = 0; i < nums; i++) {
Sehcdule[i].num = rand() % MAX_DISK; //产生0到999的随机数
Sehcdule[i].check = 0;
printf("| %d ",Sehcdule[i].num);
}
printf("|\n");
}
//检查用输入选择算法
void check_init(DiskRequest Sehcdule[MAX_SEHCDULE]) {
int algorithmic;
while (1) {
char cont; //接收判断字符
printf("输入需要执行的算法[1-4]:\n "
"[1]先来先服务\n "
"[2]最短优先\n "
"[3]电梯算法\n "
"[4]循环电梯算法\n"
"请输入:");
scanf(" %d", &algorithmic);
if (algorithmic > 4 || algorithmic < 1) {
printf("输入无效请重新输入:\n");
continue;
} else {
switch (algorithmic) {
case 1:
FCSF(Sehcdule);
break;
case 2:
SSTF(Sehcdule);
break;
case 3:
SCAN(Sehcdule);
break;
case 4:
CSCAN(Sehcdule);
break;
}
printf("是否还要选择算法来重新调度?(y/n):");
//判断输入是否输入正确
cont = check_input_yn();
if (cont == 'y') {
continue;
} else if (cont == 'n') {
break;
}
}
}
}
void CSCAN(DiskRequest Sehcdule[MAX_SEHCDULE]) {
while (true) {
int init_cscan = init;
DiskRequest CSCAN_STACK[nums];
//初始化代码
for (int i = 0; i < nums; i++) {
CSCAN_STACK[i].num = Sehcdule[i].num;
CSCAN_STACK[i].check = Sehcdule[i].check;
}
int compute = 0;
int a=0;
printf("请输入磁头移动方向\n"
"1 右边\n"
"0 左边\n"
"请输入:");
scanf("%d", &a);
//往左边
if (a == 0) {
printf("循环电梯算法磁头左边移动算法调度后磁盘队列排序为:\n");
//将列表中的值从小到大排序
for (int i = 0; i < nums; i++) {
for (int j = 0; j < nums; j++) {
if (CSCAN_STACK[i].num < CSCAN_STACK[j].num) {
int temp = CSCAN_STACK[i].num;
CSCAN_STACK[i].num = CSCAN_STACK[j].num;
CSCAN_STACK[j].num = temp;
}
}
}
//将小于于init的数将check位变成1
for (int i = 0; i < nums; i++) {
if (CSCAN_STACK[i].num < init_cscan) {
CSCAN_STACK[i].check = 1;
}
}
//将check=1的代码从大到小排序
for (int i = 0; i < nums; ++i) {
if (CSCAN_STACK[i].check == 1) {
for (int j = i + 1; j < nums; ++j) {
if (CSCAN_STACK[j].check == 1) {
if (CSCAN_STACK[i].num < CSCAN_STACK[j].num) {
int temp = CSCAN_STACK[j].num;
CSCAN_STACK[j].num = CSCAN_STACK[i].num;
CSCAN_STACK[i].num = temp;
}
}
}
}
}
//将check位不为1的值按照从大到小排序
int n = 0;
for (int i = 0; i < nums; ++i) {
if (CSCAN_STACK[i].check != 1) {
n++;
for (int j = i + 1; j < nums; ++j) {
if (CSCAN_STACK[j].check != 1) {
if (CSCAN_STACK[i].num < CSCAN_STACK[j].num) {
int temp = CSCAN_STACK[j].num;
CSCAN_STACK[j].num = CSCAN_STACK[i].num;
CSCAN_STACK[i].num = temp;
}
}
}
}
}
//先从init开始按照排序遍历
printf("| %d |", init_cscan);
int over_num;
for (int i = 0; i < nums; ++i) {
if (CSCAN_STACK[i].check == 1) {
a = CSCAN_STACK[i].num;
printf(" %d |", CSCAN_STACK[i].num);
compute += compute_num(i, CSCAN_STACK);
over_num = i;
}
}
//这里需要判断有没有大于于init的数,如果没有就没必要输出0,也没必要初始化0
if (n != 0) {
printf(" %d |", 1000);
init_cscan = 1000;
}
compute += init_cscan - CSCAN_STACK[over_num].num;
int c = 0; //判断是否为第一个不等于1的
for (int i = 0; i < nums; ++i) {
if (CSCAN_STACK[i].check != 1) {
if (c == 0) {
compute += init_cscan - CSCAN_STACK[i].num ;
c += 1;
} else {
compute += compute_num(i, CSCAN_STACK);
}
printf(" %d |", CSCAN_STACK[i].num);
}
}
}
//往右边
if (a == 1) {
printf("循环电梯算法磁头右移动算法调度后磁盘队列排序为:\n");
//将列表中的值从小到大排序
for (int i = 0; i < nums; i++) {
for (int j = 0; j < nums; j++) {
if (CSCAN_STACK[i].num > CSCAN_STACK[j].num) {
int temp = CSCAN_STACK[i].num;
CSCAN_STACK[i].num = CSCAN_STACK[j].num;
CSCAN_STACK[j].num = temp;
}
}
}
//将大于init的数将check位变成1
for (int i = 0; i < nums; i++) {
if (CSCAN_STACK[i].num > init_cscan) {
CSCAN_STACK[i].check = 1;
}
}
//将check=1的代码从小到大排序
for (int i = 0; i < nums; ++i) {
if (CSCAN_STACK[i].check == 1) {
for (int j = i + 1; j < nums; ++j) {
if (CSCAN_STACK[j].check == 1) {
if (CSCAN_STACK[i].num > CSCAN_STACK[j].num) {
int temp = CSCAN_STACK[j].num;
CSCAN_STACK[j].num = CSCAN_STACK[i].num;
CSCAN_STACK[i].num = temp;
}
}
}
}
}
//将check位不为1的值按照从小到大排序
int n = 0;
for (int i = 0; i < nums; ++i) {
if (CSCAN_STACK[i].check != 1) {
n++;
for (int j = i + 1; j < nums; ++j) {
if (CSCAN_STACK[j].check != 1) {
if (CSCAN_STACK[i].num > CSCAN_STACK[j].num) {
int temp = CSCAN_STACK[j].num;
CSCAN_STACK[j].num = CSCAN_STACK[i].num;
CSCAN_STACK[i].num = temp;
}
}
}
}
}
//先从init开始按照排序遍历
printf("| %d |", init_cscan);
int over_num;
for (int i = 0; i < nums; ++i) {
if (CSCAN_STACK[i].check == 1) {
a = CSCAN_STACK[i].num;
printf(" %d |", CSCAN_STACK[i].num);
compute += compute_num(i, CSCAN_STACK);
over_num = i;
}
}
//这里需要判断有没有大于init的数,如果没有就没必要输出1000,也没必要初始化1000
if (n != 0) {
printf(" %d |", 0);
init_cscan = 0;
}
compute += CSCAN_STACK[over_num].num - init_cscan;
int c = 0; //判断是否为第一个不等于1的值
for (int i = 0; i < nums; ++i) {
if (CSCAN_STACK[i].check != 1) {
if (c == 0) {
compute += CSCAN_STACK[i].num - init_cscan;
c++;
} else {
compute += compute_num(i, CSCAN_STACK);
}
printf(" %d |", CSCAN_STACK[i].num);
}
}
}
printf("平均移动了%d步", compute / (nums + 1));
char cont;
printf("\n是否继续输入磁盘移动方向?(y/n):");
//判断输入是否输入正确
cont = check_input_yn();
if (cont == 'y') {
continue;
} else if (cont == 'n') {
break;
}
}
}
char check_input_yn() {
char cont;
while (true) {
scanf(" %c", &cont);
if (cont == 'y' || cont == 'n') {
break;
} else {
printf("输入不正确请重新输入:");
continue;
}
}
return cont;
}
//电梯算法
void SCAN(DiskRequest Sehcdule[MAX_SEHCDULE]) {
while (true) {
int init_scan = init;
DiskRequest SCAN_STACK[nums];
//初始化代码
for (int i = 0; i < nums; i++) {
SCAN_STACK[i].num = Sehcdule[i].num;
SCAN_STACK[i].check = Sehcdule[i].check;
}
int compute = 0;
int a;
printf("请输入磁头移动方向\n"
"1 右边\n"
"0 左边\n"
"请输入:");
scanf("%d", &a);
//右边
if (a == 1) {
printf("电梯算法磁头右移动算法调度后磁盘队列排序为:\n");
//将列表中的值从小到大排序
for (int i = 0; i < nums; i++) {
for (int j = 0; j < nums; j++) {
if (SCAN_STACK[i].num > SCAN_STACK[j].num) {
int temp = SCAN_STACK[i].num;
SCAN_STACK[i].num = SCAN_STACK[j].num;
SCAN_STACK[j].num = temp;
}
}
}
//将大于init的数将check位变成1
for (int i = 0; i < nums; i++) {
if (SCAN_STACK[i].num > init_scan) {
SCAN_STACK[i].check = 1;
}
}
//将check位不为1的值按照从大到小排序
for (int i = 0; i < nums; ++i) {
if (SCAN_STACK[i].check != 1) {
for (int j = i + 1; j < nums; ++j) {
if (SCAN_STACK[j].check != 1) {
if (SCAN_STACK[i].num < SCAN_STACK[j].num) {
int temp = SCAN_STACK[j].num;
SCAN_STACK[j].num = SCAN_STACK[i].num;
SCAN_STACK[i].num = temp;
}
}
}
}
}
//将check=1的代码从小到大排序
for (int i = 0; i < nums; ++i) {
if (SCAN_STACK[i].check == 1) {
for (int j = i + 1; j < nums; ++j) {
if (SCAN_STACK[j].check == 1) {
if (SCAN_STACK[i].num > SCAN_STACK[j].num) {
int temp = SCAN_STACK[j].num;
SCAN_STACK[j].num = SCAN_STACK[i].num;
SCAN_STACK[i].num = temp;
}
}
}
}
}
//先从init开始按照排序遍历
printf("| %d |",init_scan);
for (int i = 0; i < nums; ++i) {
printf(" %d |", SCAN_STACK[i].num);
compute += compute_num(i, SCAN_STACK);
}
}
//左边
if (a == 0) {
printf("电梯算法磁头左移动算法调度后磁盘队列排序为:\n");
//将列表中的值从大到小排序
for (int i = 0; i < nums; i++) {
for (int j = 0; j < nums; j++) {
if (SCAN_STACK[i].num < SCAN_STACK[j].num) {
int temp = SCAN_STACK[i].num;
SCAN_STACK[i].num = SCAN_STACK[j].num;
SCAN_STACK[j].num = temp;
}
}
}
//小于将init的数将check位变成1
for (int i = 0; i < nums; i++) {
if (SCAN_STACK[i].num < init) {
SCAN_STACK[i].check = 1;
}
}
//将check位不为1的值按照从小到大排序
for (int i = 0; i < nums; ++i) {
if (SCAN_STACK[i].check != 1) {
for (int j = i + 1; j < nums; ++j) {
if (SCAN_STACK[j].check != 1) {
if (SCAN_STACK[i].num > SCAN_STACK[j].num) {
int temp = SCAN_STACK[j].num;
SCAN_STACK[j].num = SCAN_STACK[i].num;
SCAN_STACK[i].num = temp;
}
}
}
}
}
//将check=1的代码从大到小排序
for (int i = 0; i < nums; ++i) {
if (SCAN_STACK[i].check == 1) {
for (int j = i + 1; j < nums; ++j) {
if (SCAN_STACK[j].check == 1) {
if (SCAN_STACK[i].num < SCAN_STACK[j].num) {
int temp = SCAN_STACK[j].num;
SCAN_STACK[j].num = SCAN_STACK[i].num;
SCAN_STACK[i].num = temp;
}
}
}
}
}
//先从init开始按照排序遍历
// int f = 0; //检查第一个
printf("| %d |", init_scan);
for (int i = 0; i < nums; ++i) {
if (SCAN_STACK[i].num < init_scan) {
printf(" %d |", SCAN_STACK[i].num);
compute += compute_num(i, SCAN_STACK);
}
}
for (int i = 0; i < nums; ++i) {
if (SCAN_STACK[i].num > init_scan) {
printf(" %d |", SCAN_STACK[i].num);
compute += compute_num(i, SCAN_STACK);
}
}
}
printf("平均移动了%d步",compute/(nums+1));
char cont;
printf("\n是否继续输入磁盘移动方向?(y/n):");
//判断输入是否输入正确
cont = check_input_yn();
if (cont == 'y') {
continue;
} else if (cont == 'n') {
break;
}
}
}
void FCSF(DiskRequest Sehcdule[MAX_SEHCDULE]) {
DiskRequest FCSF_STACK[nums];
//初始化代码
for (int i = 0; i < nums; i++) {
FCSF_STACK[i].num = Sehcdule[i].num;
FCSF_STACK[i].check = Sehcdule[i].check;
}
int compute=0;
printf("先到先服务算法调度磁盘排序后的队列:\n"
"| %d ",init);
//直接按照随机生成的列表顺序便利就好了
for(int i = 0 ; i <nums;i++){
printf("| %d ",FCSF_STACK[i].num);
compute += compute_num(i,FCSF_STACK);
}
printf("| 平均移动了%d步\n",compute/(nums+1));
}
void SSTF(DiskRequest Sehcdule[MAX_SEHCDULE]) {
DiskRequest SSTF_STACK[nums];
//初始化代码
for (int i = 0; i < nums; i++) {
SSTF_STACK[i].num = Sehcdule[i].num;
SSTF_STACK[i].check = Sehcdule[i].check;
}
int compute = 0;
int a[nums]; //存储磁头位置数减去剩余队列内位置
printf("最短优先算法调度后磁盘队列排序为:\n"
"| %d ", init);
//第一次init是在输入的磁磁道位置
for (int i = 0; i < nums; i++) {
//求初始位置和队列内每个磁道位置的距离,如果大于就是初始位置减去,小于就是队列内位置减去出书位置
if (SSTF_STACK[i].num > init) {
a[i] = SSTF_STACK[i].num - init;
} else {
a[i] = init - SSTF_STACK[i].num;
}
}
//求出磁道现在位置和剩余队列磁道位置后,开始比较
for (int i = 0; i < nums; i++) {
for (int j = i + 1; j < nums; j++) {
//比较a数字内的值,他们的每个值都与Sehcdule队列保持对齐
if (a[i] > a[j]) {
//Sechdule和a中的值都需要进行交换
int temp = SSTF_STACK[j].num;
SSTF_STACK[j].num = SSTF_STACK[i].num;
SSTF_STACK[i].num = temp;
temp =a[i];
a[i] = a[j];
a[j] = temp;
}
}
compute += compute_num(i,SSTF_STACK);
printf("| %d ",SSTF_STACK[i].num);
}
printf("| 平均移动了%d步\n",compute/(nums+1));
}
//计算每一步走了多长的距离
int compute_num(int i,DiskRequest Sehcdule[MAX_SEHCDULE]) {
int compute = 0;
//如果是调度列表开头就表示他上一个值是初始值,就和初始值计算
if(i==0){
if(Sehcdule[i].num > init){
compute = Sehcdule[i].num - init;
} else{
compute = init - Sehcdule[i].num;
}
//上一个不是初始值就拿他和他的上一个计算
}
else{
if(Sehcdule[i-1].num>=Sehcdule[i].num) {
compute += Sehcdule[i - 1].num - Sehcdule[i].num;
} else{
compute +=Sehcdule[i].num - Sehcdule[i-1].num;
}
}
return compute;
}