链表实现磁盘调度算法


  
  

  磁盘调度算法

要求模拟先来先服务法(First-Come, First-Served,FCFS),最短寻道时间优先法(Shortest Seek Time First, SSTF),电梯法三种磁盘调度算法,输入为一组请求访问磁道序列,输出为每种调度算法的磁头移动轨迹和移动的总磁道数。

 

实验代码:

/*
1、FCFS
2、SSTF
3、SCAN
测试队列(课本P202):98、183、37、122、14、124、65、67
*/ 
#include <iostream>
using namespace std;
typedef struct Node
{
	int value;           /*数据域*/
	Node *next;         /*指针域*/
}LinkNode,*LinkList;
void Show(LinkList Queue)
{
	LinkNode *p = Queue;
	while (p)
	{
		cout << p->value << ' ';
		p = p->next;
	}
	cout << endl;
}
void CopyQueue(LinkList Queue, LinkList &QueueCopy)
{
	LinkList q1, q2, p; int i = 0;                                 //q是CopyQueue的活动指针
	QueueCopy =new LinkNode;                       //创建链表副本的第一个结点
	QueueCopy->next = NULL;
	q1 = q2 = QueueCopy;
	p = Queue;
	while (p)
	{
		q2->value = p->value;
		i++;
		//cout << "拷贝第" << i << "个结点的值" << q2->value << endl;
		if (p->next)
		{			
			q2 = new LinkNode;
			q2->next = q1->next;
			q1->next = q2;
			q1 = q1->next;
		}
		p = p->next;
	}
	q2->next = NULL;
}
void swap(int &a,int &b)    /*交换函数*/
{
	
		int temp;
		temp = a;
		a = b;
		b = temp;
	
}
void HeadInsert(LinkList &QueueHead,LinkList InsertQueue)   /*用头插法将Queue结点插入QueueTemp,使得原队列逆序*/
{
	LinkNode *p = InsertQueue;
	while (p)
	{
		LinkNode *QueueNode = new LinkNode;
		QueueNode->value = p->value;
		//cout << "已插入:" << p->value << endl;
		QueueNode->next = QueueHead->next;
		QueueHead->next = QueueNode;
		p = p->next;
	}
	//cout << "头插测试:" <<endl;
	//Show(QueueHead);
}
void HeadInsert(LinkList &QueueHead, LinkList InsertQueue,LinkNode *len)   /*用头插法将Queue结点插入QueueTemp,使得原队列逆序*/
{
	LinkNode *p = InsertQueue;
	while (p!=len->next)
	{
		LinkNode *QueueNode = new LinkNode;
		QueueNode->value = p->value;
		//cout << "已插入:" << p->value << endl;
		QueueNode->next = QueueHead->next;
		QueueHead->next = QueueNode;
		p = p->next;
	}
	//cout << "头插测试:" <<endl;
	//Show(QueueHead);
}
void QueueSort(LinkList &Queue)
{//采用冒泡排序
	LinkNode *p = Queue; int count = 0;
	while (p->next != NULL)
	{
		count++;
		p = p->next;
	}
	//cout << "计算排序趟数:" <<count<< endl;
	for (int i = 0; i < count;i++)             
	{
		p = Queue;
		//cout <<"第"<<i<<"趟排序:"<< endl;
		for (int j = 0; j < count - i;j++)
		{
		//	cout << "第" << j <<"次交换"<< endl;
			if (p->value > p->next->value)
				swap(p->value, p->next->value);
			//Show(Queue);
			p = p->next;
		}
		//cout << endl;
	}
	//cout << "\n验证QueueSort:" << endl;
	//Show(Queue);
	//cout << endl;
}
void CreateQueue(LinkList &Queue)
{
	int QueueLength;                              /*队列长度*/
	LinkNode *QueueHead,*QueueNode1,*QueueNode2;
	QueueHead = QueueNode1 = QueueNode2 = NULL;
	cout << "请输入所要访问磁道队列的长度:";
	cin >> QueueLength; 
	cout << "请输入所要访问磁道队列:";
	for (int i = 0; i < QueueLength; i++)          /*采用尾插法插入*/
	{
		if (i == 0)
		{
			QueueHead = new LinkNode;
			cin >> QueueHead->value;               /*输入头结点*/
			QueueHead->next = NULL;
			QueueNode1 = QueueNode2 = QueueHead;
		}
		else
		{
			QueueNode2 = new LinkNode;
			cin >> QueueNode2->value;               /*输入其它结点*/
			QueueNode2->next = QueueNode1->next;
			QueueNode1->next = QueueNode2;
			QueueNode1 = QueueNode2;
		}
	}
	QueueNode2->next = NULL;
	Queue = QueueHead;
}

int MoveSum(LinkList Queue)
{
	LinkNode *p = Queue; int count = 0,sum=0;
	while (p->next != NULL)
	{
		count++;
		p = p->next;
	}
	p = Queue;	
	for (int i = 0; i < count; i++)
	{
		//	cout << "第" << i <<"次求和"<< endl;
		sum += ((p->value) > (p->next->value) ? ((p->value) - (p->next->value)) : ((p->next->value) - (p->value)));
		p = p->next;
	}
	return sum;


}
void FCFS(LinkList Queue,int start)
{
	cout << "\nFCFS磁头移动轨迹:" << endl;
	LinkList QueueCopy, QueueTemp;
	CopyQueue(Queue, QueueCopy);
	QueueTemp = new LinkNode;
	QueueTemp->value = start;
	QueueTemp->next = QueueCopy;	
	Show(QueueTemp);
	cout << "移动磁道数:" ;
	cout << MoveSum(QueueTemp) << endl;
}

void SSTF(LinkList Queue, int start)
{
	cout << "\nSSTF磁头移动轨迹:" << endl;
	LinkList QueueCopy, QueueTemp;   /*QueueCopy队列副本,QueueTemp临时队列,QueueNode队列结点*/
	LinkNode *first,*tail,*p, *QueueNode; /*first为第一个结点的指针,tail为尾结点指针,p为工作指针*/
	p = first = tail = NULL;
	CopyQueue(Queue, QueueCopy);
	//cout << "显示Copy队列:" ;
	//Show(QueueCopy);
	QueueSort(QueueCopy);
	//cout << "显示排序后的Copy队列:";
	//Show(QueueCopy);
	for (p= QueueCopy; p->next; p = p->next);
	tail = p;
	first = QueueCopy;
	QueueNode = new LinkNode;
	QueueNode->value = start;
	QueueNode->next = NULL;
	QueueTemp = QueueNode;
	if (first->value >= start)    /*将开始磁道号加入队列的首部*/
	{		
		QueueTemp->next = QueueCopy;
		Show(QueueTemp);
		cout << "移动磁道数:";
		cout << MoveSum(QueueTemp) << endl ;
	}
	else if (tail->value <= start)   /*,将原队列逆序,并将开始磁道号加入新队列的首部*/
	{			
		HeadInsert(QueueTemp, QueueCopy);
		Show(QueueTemp);
		cout << "移动磁道数:";
		cout << MoveSum(QueueTemp) << endl;
	}
	else
	{
		int delta1, delta2;           /*记录两个数的绝对值*/		
		LinkNode *left, *right, *pre;       /*left和right是开始磁道号的左右结点位置,pre是left结点的前一个结点指针*/
		left = first;                 /*左指针初始化为链表的首结点 */
		right = left->next;
		pre = NULL;
		//创建访问的队列
		//QueueTemp=new LinkNode;		  /*记录访问列表的第一个值*/
		//LinkNode *pt= QueueTemp;
		//QueueTemp->value = start;
		//QueueTemp->next = NULL;	
		p = QueueTemp;
		while (left&&right)
		{	
			//first = QueueCopy;
			left = first;                 /*左指针初始化为链表的首结点 */
			right = left->next;
			pre = NULL;
			while (right->value < start)
			{//右指针的结点值小于开始磁道号,左右指针右移
				pre = left;     //4 5 6 7 8      6
				left = left->next;
				right = left->next;
			}
			//cout << "上一个磁道号:" << start << endl;
			delta1 = (((left->value)>start) ? left->value - start : start - left->value);
			//cout << "左结点的值:" << left->value << endl;
					
			delta2 = (((right->value)>start) ? right->value - start : start - right->value);
			//cout << "右结点的值:" << right->value << endl;
			//cout << "开始磁道号与左结点的差值:" << delta1 << endl;
			//cout << "开始磁道号与右结点的差值:" << delta2 << endl<<endl<<endl;		
			if (delta1 < delta2)
			{
				start = left->value;
				//将要访问的结点加入访问队列
				QueueNode = new LinkNode;
				QueueNode->value = start;
				QueueNode->next = p->next;
				p->next = QueueNode;
				p = p->next;
				if (pre)
				{
					pre->next = right;
				}
				else
				{
					QueueCopy = QueueCopy->next;
					left = pre;					
				}	           /*删除已访问的结点*/
				//cout << "第四个结点值测试:" << QueueTemp->next->next->next->value << endl;
				delete left;  
				left = pre;
			}
			else
			{
				start = right->value;
				//将要访问的结点加入访问队列
				QueueNode = new LinkNode;
				QueueNode->value = start;
				QueueNode->next = p->next;
				p->next = QueueNode;
				p = p->next;
				left->next = right->next;    /*删除已访问的结点*/
				//cout << "第二个结点值测试:" << QueueTemp->next->value << endl;
				delete right;
				right = left->next;
			}
//			pt = pt->next;
		}
		for (p = QueueTemp; p->next; p = p->next);
		tail = p;
		if (right)                   /*左指针移到空指针的位置*/
			tail->next = QueueCopy;
		else
			HeadInsert(tail,QueueCopy);
		Show(QueueTemp);
		cout << "移动磁道数:";
		cout << MoveSum(QueueTemp) << endl;
	
	}
	
}
void SCAN(LinkList Queue, int start)
{
	cout << "\nSCAN磁头移动轨迹:" << endl;
	int status;
	cout << " ---------------------温馨提示------------------" << endl;
	cout << "+ 请选择电梯法的模式:                          +" << endl;              
	cout << "+ 1.先↓后↑                                    +" << endl;                          
	cout << "+ 2.先↑后↓                                    +" << endl;
	cout << " -----------------------------------------------" << endl;
	cout << "选择模式:";
	cin >> status;
	if ((status!=1)&&(status!=2))
	{
		int i = 1;
		cout << "无效的输入,请重试!"<<endl<<endl;
		for (i = 1; i <= 3; i++)
		{
			cout << "选择模式:";
			cin >> status;
			if (status == 1 || status == 2)
				break;
			cout << "无效的输入,请重试!" << endl << endl;
		}	
		if (i == 4)
		{
			cout << "输入错误次数过多,请重新运行程序!" << endl << endl;
			return;
		}
	}
	LinkList QueueCopy, QueueTemp;   /*QueueCopy队列副本,QueueTemp临时队列,QueueNode队列结点*/
	LinkNode *first, *tail, *p, *QueueNode; /*first为第一个结点的指针,tail为尾结点指针,p为工作指针*/
	p = first = tail = NULL;
	CopyQueue(Queue, QueueCopy);
	//cout << "显示Copy队列:" ;
	//Show(QueueCopy);
	QueueSort(QueueCopy);
	//cout << "显示排序后的Copy队列:";
	//Show(QueueCopy);
	for (p = QueueCopy; p->next; p = p->next);
	tail = p;
	first = QueueCopy;
	QueueNode = new LinkNode;
	QueueNode->value = start;
	QueueNode->next = NULL;
	QueueTemp = QueueNode;
	switch (status)
	{
	case 1:
	{
	
		if (first->value >= start)    /*将开始磁道号加入队列的首部*/
		{
			 ;
			QueueTemp->next = QueueCopy;
			Show(QueueTemp);
			cout << "移动磁道数:";
			cout << MoveSum(QueueTemp) << endl;
		}
		else if (tail->value <= start)   /*,将原队列逆序,并将开始磁道号加入新队列的首部*/
		{			
			HeadInsert(QueueTemp, QueueCopy);
			Show(QueueTemp);
			cout << "移动磁道数:";
			cout << MoveSum(QueueTemp) << endl;
		}
		else
		{
			LinkNode *cre=first,*pre=NULL;     /*当前工作指针*/
			while (cre->value < start)
			{
				pre = cre;
				cre = cre->next;
			}
			if (pre&&cre->value>start)
				HeadInsert(QueueTemp, QueueCopy, pre);
			else if(cre->value==start)
				HeadInsert(QueueTemp, QueueCopy, cre);
			for (p = QueueTemp; p->next; p = p->next);
			tail = p;
			tail->next = cre->next;
			Show(QueueTemp);
			cout << "移动磁道数:";
			cout << MoveSum(QueueTemp) << endl;
		}
	}; break;
	case 2:
	{

		if (first->value >= start)    /*将开始磁道号加入队列的首部*/
		{
			;
			QueueTemp->next = QueueCopy;
			Show(QueueTemp);
			cout << "移动磁道数:";
			cout << MoveSum(QueueTemp) << endl;
		}
		else if (tail->value <= start)   /*,将原队列逆序,并将开始磁道号加入新队列的首部*/
		{
			HeadInsert(QueueTemp, QueueCopy);
			Show(QueueTemp);
			cout << "移动磁道数:";
			cout << MoveSum(QueueTemp) << endl;
		}
		else
		{
			LinkNode *cre = first,*pre=NULL;     /*当前工作指针*/
			while (cre->value < start)
			{
				pre = cre;
				cre = cre->next;
			}
			QueueTemp->next = cre;
			for (p = QueueTemp; p->next; p = p->next);
			tail = p;
			if(pre)
			HeadInsert(tail, QueueCopy, pre);			
			Show(QueueTemp);
			cout << "移动磁道数:";
			cout << MoveSum(QueueTemp) << endl;
		}
	}; break;
	default:
	 	break;
	}

}
int main()
{
	int status;
	cout << " ----------------实验八 磁盘调度算法------------" << endl;
	cout << "+  请选择磁盘调度算法:                          +" << endl;
	cout << "+  1.FCFS                                       +" << endl;
	cout << "+  2.SSTF                                       +" << endl;
	cout << "+  3.SCAN                                       +" << endl;
	cout << " -----------------------------------------------" << endl;
	cout << "选择算法(序号):";
	cin >> status;
	if ((status != 1) && (status != 2)&&(status != 3))
	{
		int i = 1;
		cout << "无效的输入,请重试!" << endl << endl;
		for (i = 1; i <= 3; i++)
		{
			cout << "选择算法(序号):";
			cin >> status;
			if (status == 1 || status == 2||status==3)
				break;
			cout << "无效的输入,请重试!" << endl << endl;
		}
		if (i == 4)
		{
			cout << "输入错误次数过多,请重新运行程序!" << endl << endl;
			return 0;
		}
	}
	int start;              /*开始的磁道号*/
	LinkList Queue;	
	CreateQueue(Queue);      /*创建要访问的磁盘服务队列*/
	cout << "请输入初始磁道号:";
	cin >> start;	
	switch (status)
	{
	case 1:
		FCFS(Queue, start); break;
	case 2:		
		SSTF(Queue, start); break;
	case 3:
		SCAN(Queue, start); break;
	default:
		break;
	}
	cout << endl;
	cout << " -----------------------------------------------" << endl;
	cout << "+  姓名:     XXX                              +" << endl;
	cout << "+  学号:     XXXXXXXXX                        +" << endl;
	cout << "+  班级:     XXXXXX                           +" << endl;
	cout << "+  指导老师: XXXX                             +" << endl;
	cout << " -----------------------------------------------" << endl;	
	return 0;
}

运行结果:

1、FCFS

2、SSTF

3、SCAN

(1)先下后上

(2)先上后下



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值