使用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;
}