1.最短寻道优先算法SSTF:该算法选择这样的进程:其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短。
2.扫描算法SCAN:该算法不仅考虑到欲访问的磁道与当前磁道间的距离,更优先考虑的是磁头当前的移动方向。例如,当磁头正在自里向外移动时,SCAN算法所考虑的下一个访问对象,应是其欲访问的磁道既在当前磁道之外,又是距离最近的。这样自里向外地访问,直至再无更外的磁道需要访问时,才将磁臂换向为自外向里移动。
#include<iostream>
#include<time.h>
#include<Windows.h>
#include<string>
using namespace std;
#define MAX 200
int Move;//移动距离
int direction;//移动方向
int set[MAX];//存储访问序列
int lable[MAX];//标签数组,存放整理后的序列
int lenth = 0;//个数,即有效占用数组里的的长度
int x = 0;//记磁头处标号
//创建访问序列
void Create() {
int n = 0;
int k = 0;
//用前初始化
for (int i = 0;i < MAX;i++) {
set[i] = -1;
lable[i] = -1;
}
retry:
cout << "========================================" << endl;
cout << "#输入1自动生成#\n#输入2手动输入#" << endl;
cout << "========================================" << endl;
cout << "请输入:";
cin >> k;
if (k == 1) {
cout << "========================================" << endl;
cout << "请输入磁道个数以生成随机磁道号:";
cin >> n;
cout << "生成磁道号为 :";
srand((unsigned)time(NULL)); //给srand提供种子,unsigned int类型,取值范围0-65565
for (int i = 0;i < n;i++)
{
set[i] = (rand() % MAX) + 1; //rand根据srand种子值返回一个随机数
cout << set[i] << " ";
}
}
else if(k == 2) {
cout << "========================================" << endl;
cout << "请输入磁道个数:";
cin >> n;
cout << "输入磁道号为 :";
for (int i = 0;i <n;i++) {
cin >> set[i];
}
}
else {
system("cls");
goto retry;
}
cout << "\n========================================\n" << endl;
lenth = n;
}
//移动距离计算
int Cal(int a, int b) {
return(a > b ? a - b : b - a);
}
//路径显示
void Showpath(int a[], int x, int len) {
cout << "========================================" << endl;
cout << "从" << x << "号磁道开始:" << endl;
for (int i = 1;i < len + 5;i++) {
int j = i;
if (a[1] == x) {
j = i + 1;
}
//将选定已有随机磁道开始时set[len]为-1情况剔除
if (a[j] >= 0 && a[j] <= MAX) {
cout << "到下一个磁道是:" << a[j] << "\t移动距离为:" << Cal(a[j - 1], a[j]) << endl;
Sleep(500);
}
}
cout << "========================================" << endl;//38*=
}
//平均寻道长度
void Cal_aver(int a[], int x, int len) {
float all = 0;
float average = 0;
for (int i = 1;i < len + 1;i++) {
all += Cal(a[i - 1], a[i]);
}
average = all / len;
cout << "平均寻道长度为:" << average << endl;
cout << "========================================" << endl;
}
//SSTF最短寻道
void SSTF(int a[], int x, int len) {
cout << "========================================" << endl;
cout << "已选择从" << x << "号" << "开始执行:" << endl;
lable[0] = x;
int m = 0;
int temp = 0;
//找出访问序列
for (int i = 0;i < len;i++) {
int m = i;
//找到离当前最近的一磁道
for (int j = i;j < len;j++) {
//set[j+1]条件防止数据读取超出len长度
if (Cal(set[j + 1], lable[i]) < Cal(set[m], lable[i]) && set[j + 1] >= 0) {
m = j + 1;
temp = set[j + 1];
}
else {
temp = set[m];
}
}
lable[i + 1] = temp;
//找到后,将其跳出下一循环(跳出循环时总会是m
int temp1 = set[m];
set[m] = set[i];
set[i] = temp1;
}
Showpath(lable, x, len);
Cal_aver(lable, x, len);
}
//SCAN电梯调度
void SCAN(int a[], int x, int len) {
cout << "========================================" << endl;
cout << "已选择从" << x << "号" << "开始执行:" << endl;
int m = 0;
int temp = 0;
int* p1 = new int[len]; //存放排列好的序列
for (int i = 0; i < len; i++)p1[i] = set[i];
//排列好的磁道号自小至大冒泡
for (int i = 0;i < len - 1;i++) {
for (int j = 0;j < len - 1 - i;j++) {
if (p1[j + 1] < p1[j]) {
temp = p1[j + 1];
p1[j + 1] = p1[j];
p1[j] = temp;
}
}
}
//选出最近一磁道号,确定扫描方向
lable[0] = x;
m = 0;
int temp_2 = 0;//x若在p1[[]中,存p1[]中x所在下标,否则存与x最近值的下标
for (int j = 0;j < len - 1;j++) {
//条件p1[j+1]跳过与lable下标0,1相同的磁盘号
if (Cal(p1[j + 1], lable[0]) < Cal(p1[m], lable[0]) && p1[j + 1] != x) {
m = j + 1;
temp = p1[j + 1];
}
else {
temp = p1[m];
}
lable[1] = temp;
if (p1[j] == x) {
temp_2 = j;
break;
}
else {
temp_2 = m;
}
}
//若电梯上楼
if (lable[1] - lable[0] > 0) {
direction = 1;
}
else {
direction = 0;
}
//给lable[]整上
m = temp_2;//此m为p1[]中被指定开始那个磁盘号的下标
temp = m;
int k = p1[m];
for (int i = 1;i < len + 1;i++) {
//若下楼
if (direction == 0) {
if (m > 0) {
//保证lable[]不出错
if (lable[0] != p1[m] && i == 1) {
i += 1;
lable[i] = p1[m - 1];
m--;
}
else {
lable[i] = p1[m - 1];
m--;
}
}
if (m <=0) {
direction = 1;
m = temp;
//保证lable[]不出错
if (lable[0] == k) {
i += 1;
}
}
}
else {
//if防止访问出界
if (m < len - 1) {
if (lable[0] != p1[m] && i == 1) {
i += 1;
lable[i] = p1[m + 1];
m++;
}
else {
lable[i] = p1[m + 1];
m++;
}
}
if (m >= len-1) {
direction = 0;
m = temp;
if (lable[0] == k) {
i += 1;
}
}
}
}
Showpath(lable, x, len);
Cal_aver(lable, x, len);
delete[] p1;
}
int main() {
int select = 0;
system("mode con:cols=40 lines=40");
system("color 10");
Sleep(100);
system("color 20");
Sleep(100);
system("color 30");
Sleep(100);
system("color 40");
Sleep(100);
system("color 50");
Sleep(100);
system("color 60");
Sleep(100);
system("color e0");
while (1) {
cout << "========================================" << endl;
cout << "================= ORDER=================" << endl;
cout << "===============0:退出程序==============" << endl;
cout << "===============1:SSTF算法==============" << endl;
cout << "===============2:SCAN算法==============" << endl;
cout << "========================================" << endl;
cout << "\n你的选择:";
cin >> select;
cout << "正在执行:" << endl;
switch (select)
{
case 0: {
cout << "\n退出成功!" << endl;
system("color 10");
Sleep(100);
system("color 20");
Sleep(100);
system("color 30");
Sleep(100);
system("color 40");
Sleep(100);
system("color 50");
Sleep(100);
system("color 60");
Sleep(100);
system("color 0f");
exit(0);
}
case 1: {
Create();
Sleep(500);
cout << "========================================" << endl;
cout << "请选择磁头处当前磁道号(1~" << MAX << "):";
cin >> x;
SSTF(set, x, lenth);
system("pause");
system("cls");
break;
}
case 2: {
Create();
Sleep(500);
cout << "========================================" << endl;
cout << "请选择磁头处当前磁道号(1~" << MAX << "):";
cin >> x;
SCAN(set, x, lenth);
system("pause");
system("cls");
break;
}
default: {
system("cls");
}
}
}
return 0;
}