广工 操作系统课程设计 最佳适应算法最坏适应算法循环首次适应算法.docx
《广工 操作系统课程设计 最佳适应算法最坏适应算法循环首次适应算法.docx》由会员分享,可在线阅读,更多相关《广工 操作系统课程设计 最佳适应算法最坏适应算法循环首次适应算法.docx(19页珍藏版)》请在冰豆网上搜索。
广工操作系统课程设计最佳适应算法最坏适应算法循环首次适应算法
动态分区分配算法仿真,循环首次适应算法、最佳适应算法、最坏适应算法
#include
#include//在输入输出流中用到控制符
#include//用到了SetConsoleTextAttribute函数
#defineminsize2//事先规定的不再切割的剩余分区大小为2
usingnamespacestd;
structNode
{
intname;
intstart;
intsize;
intstate;
Node*pre;
Node*next;
};
typedefstructDlinklist
{
Node*head;
}Dlist;
//===================
Dlistpro,fre;
intmemory,name,size,fit;
Node*temp=NULL;//temp是NestFit算法中的起始查寻指针
//===================
voidinitDlist(Dlist&L)//创建带有头结点的双向链表
{
L.head=newNode;
L.head->next=L.head->pre=NULL;
}
voidMemoryInit()//初始化两个链表
{
initDlist(pro);//process链表
initDlist(fre);//freeblock链表
Node*p=newNode;
p->name=0;
p->start=0;
p->state=0;
p->size=memory;
p->next=NULL;//这里曾错写成p->pre..............
p->pre=fre.head;//这里曾漏写
fre.head->next=p;
}
intgetLength(Dlist&L)//返回链表的长度,即元素的个数
{
intm=0;
Node*p=L.head->next;
while(p!
=NULL)
{
m++;
p=p->next;
}
returnm;
}
voidarrangeSmaller(Dlist&L)//冒泡排序,链表按size进行排序,从小到大
{
intlength=getLength(L);
for(inti=0;i=2的时候才排序
{
Node*p=L.head->next;
Node*q=p->next;
inta,b,c,d;//==========================================================================
for(intj=0;j{
if(p->size>q->size)//交换位置,如果前面的大于后面的,使小的上浮,如果两个相等,则还是原来在前的保持在前
{
a=p->size;
p->size=q->size;
q->size=a;
b=p->name;
p->name=q->name;
q->name=b;
c=p->start;
p->start=q->start;
q->start=c;
d=p->state;//==========================================================================
p->state=q->state;
q->state=d;
}
p=p->next;
q=p->next;
}
}
}
voidarrangeBigger(Dlist&L)//链表按size进行排序,从大到小
{
intlength=getLength(L);
for(inti=0;i{
Node*p=L.head->next;
Node*q=p->next;
inta,b,c,d;
for(intj=0;j{
if(p->sizesize)
{
a=p->size;
p->size=q->size;
q->size=a;
b=p->name;
p->name=q->name;
q->name=b;
c=p->start;
p->start=q->start;
q->start=c;
d=p->state;//==========================================================================
p->state=q->state;
q->state=d;
}
p=p->next;
q=p->next;
}
}
}
voidarrangeStart(Dlist&L)//链表按start递增排序
{
intlength=getLength(L);
for(inti=0;i{
Node*p=L.head->next;
Node*q=p->next;
inta,b,c,d;
for(intj=0;j{
if(p->start>q->start)
{
a=p->size;
p->size=q->size;
q->size=a;
b=p->name;
p->name=q->name;
q->name=b;
c=p->start;
p->start=q->start;
q->start=c;
d=p->state;//==========================================================================
p->state=q->state;
q->state=d;
}
p=p->next;
q=p->next;
}
}
}
voidDlistInsert(Dlist&L,Nodee)//在头结点之后插入元素,即L.head->next指向e
{
Node*p=newNode;
p->name=e.name;
p->size=e.size;
p->start=e.start;
p->state=e.state;
if(L.head->next!
=NULL)//这是个值得注意的地方,L.head->next==NULL,则没有指针L.head->next->pre,如果这里不加判断的话,会出错
L.head->next->pre=p;
p->next=L.head->next;
p->pre=L.head;
L.head->next=p;
//双向链表,插入一个新的元素,如果元素不是插入在链尾,则一共要修改四次指针
}
voidDlistDelete(Node*p,Node&e)//传递指针p,删除指针p指向的链表元素,用Node型变量e记录该元素的相关数据
{
e.name=p->name;
e.start=p->start;
e.size=p->size;
e.state=p->state;
p->pre->next=p->next;//这里曾写成=p->pre....
if(p->next!
=NULL)
p->next->pre=p->pre;//这里曾写成p->next->pre=p,留意
delete(p);//删除一个元素修改一次或两次指针
}
//=======================
voidGreen()
{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);}
voidRed()
{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);}
voidWhite()
{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);}
voidYellow()
{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN);}
//=======================
voidBestOrWorst()
{
arrangeStart(fre);//先按地址递增排序
if(fit==1)
arrangeSmaller(fre);//再按size递增排序,当两个空闲区的size一样时,由于先按地址递增排序了,所以还是地址低的在前。
if(fit==2)
arrangeBigger(fre);
Nodee;
intflag=0;
Node*p=fre.head->next;/*p=fre.head->next,而这时fre是不可能为空的,因为在input()中加入了判断,如果输入了allocate的请求时,如果fre为空,则不会执行BestOrWorst()
故不用讨论fre是否为空的情况。
也就是说,在进入BestOrWorst()的时候就已经确保了fre.head->next!
=NULL,同理,进入NextFit()的时候也保证了fre不为空*/
while(p!
=NULL)
{//遍历fre链表,当找到合适的空间之后就break
if(p->size>=size)
{
flag=1;
break;//一定要break不然遇到两个size相同的空闲区就会出现两个都分配出去的状况
}
p=p->next;
}
if(flag==0)//在fre链表不空的前提下,如果flag==0则说明没有找到合适的空闲区间,所以分配失败
{
Red();
cout<<"Nofittingblock,failedtoallocatememory!
!
"<}
else
{
if(p->size-size<=minsize)
{
p->state=2;//==========================================================================
DlistDelete(p,e);
e.name=name;//这里注意了,不是e.name=p->name因为fre链表中所有的name全部被我置为0,所以当把空闲区间分配给process的时候一定要记得把名字加进去
//其实state对操作什么的都完全没有影响,可改可不改,但为了规范,还是改一下吧
DlistInsert(pro,e);/*这里还有的一个问题是,例如,当输入的信息为name=1,size=48KB,而将要分配给它的空闲区间p->size=50,这样,当在表格中输出的时候
该process的信息是name=1,size=50KB,也就是说它的实际大小向p->size看齐了,但如果这里让e.size=size的话,输出来的信息确实跟原来输入
的时候对应了,但是当kill这个进程的时候,回收的空间并不等于之前分配出去时的空间,会导致memory发生变化*/
}
else
{
e.state=2;//==========================================================================
e.name=name;//同理
e.start=p->start;
//e.state=1;
e.size=size;
DlistInsert(pro,e);
p->start=p->start+size;//只要修改一下原来空闲区间的start和size即可
p->size=p->size-size;
p->state=2;//==================================================
}
Yellow();
cout<<"Memoryallocated"<}
}
voidNextFit()
{
arrangeStart(fre);
Nodee;
Node*p=NULL;
//在这里不用讨论fre是否为空,因为只有fre不为空才会执行NextFit(),详情请看input()
intflag=0;
intlength=getLength(fre);
if(temp==NULL)//if(length==1||temp==NULL)当上一次进行分配的空间为链尾元素,则temp会指向NULL,这里加了个length==1,是因为
p=fre.head->next;//第一次执行NextFit()的时候,Node*temp=newNode,但是后来改进了,直接在声明temp的时候就让temp=NULL,这样一来,第一次执行NextFit()的时候也能通过
else
p=temp;
while(length>0)
{
if(p->size>=size)
{
flag=1;
break;
}
length--;
if(p->next==NULL)//这里也是值得注意的地方
p=fre.head->next;
else
p=p->next;
}
if(flag==0)//没有找到合适的空闲区间来进行分配
{
Red();
cout<<"Nofittingblock,failedtoallocatememory!
!
"<}
else
{
if(p->size-size<=minsize)
{
//因为reclaim操作并不会减少fre中的元素,只有可能增加而已,所以只要在这个函数体内记录好temp就行。
//只有这一步操作才会减少fre中的元素,如果移出的元素是链尾元素(或者是fre中只有这个元素),则temp==NULL,如果不是则temp=p->next
temp=p->next;//应该p指针发生改变之前就执行该操作,保证了temp=p->next,
DlistDelete(p,e);
e.name=name;//注意了,因为fre里面所有的name都置零了,所以弹出来之后要修改一下再放入pro中
e.state=2;//====================================================================
DlistInsert(pro,e);
}
else
{
e.name=name;
e.start=p->start;
e.state=2;//====================================================================
e.size=size;
DlistInsert(pro,e);
p->start=p->start+size;
p->size=p->size-size;
p->state=2;//====================================================================
temp=p->next;//这里注意了,这是跟BestOrWorst()不同。
}
Yellow();
cout<<"Memoryallocated"<}
}
voidReclaimMemory()
{
intflag=0;
Nodee;
Node*t=NULL;
Node*s=pro.head->next;//在这里不讨论s==NULL的情况,因为我在后面intput()函数中有补充
while(s!
=NULL)
{
if(s->name==name)
{
flag=1;
break;//一定要break
}
s=s->next;
}
if(flag==1)
{
arrangeStart(fre);
Node*p=fre.head->next;
if(p==NULL)
{
DlistDelete(s,e);
e.name=0;
e.state=2;////====================================================================
DlistInsert(fre,e);
}
else
{
while(p!
=NULL)//遍历fre链表
{
if(p->start+p->size==s->start&&(p->next==NULL||p->next->start!
=s->start+s->size))//当回收区与前一个空闲区邻接
{
p->state=2;//==========================================================================
p->size=p->size+s->size;
DlistDelete(s,e);//要记得删除pro链表中指针s对应的元素
break;//一定要留意,一旦找到了符合条件的元素,执行完之后一定要break
}
if(s->start+s->size==p->start&&(p->pre==fre.head||p->pre->start+p->pre->size!
=s->start))//当回收区与后一个空闲区邻接
{
p->state=2;//==========================================================================
p->size=p->size+s->size;
p->start=s->start;
DlistDelete(s,e);
break;
}
if(p->start+p->size==s->start&&p->next!
=NULL&&p->next->start==s->start+s->size)//回收区与前后空闲区邻接
{
t=p->next;
p->state=2;//==========================================================================
p->size=p->size+s->size+t->size;
DlistDelete(t,e);
DlistDelete(s,e);
break;
}
p=p->next;
}
if(p==NULL)//遍历完fre链表之后发现没有一个元素满足上面三种情况,则在链首部插入该回收区
{
DlistDelete(s,e);
e.name=0;
e.state=2;//==========================================================================
DlistInsert(fre,e);
arrangeStart(fre);//由于是在链首插入回收区,所以还是排一下序
}
}
Yellow();
cout<<"Process"<}
else
{
Red();
cout<<"Nomatchingprocess!
!
"<}
}
voidoutput()
{
//每次执行完输入的请求操作之后两条链表中发生过变动的元素的state==2,output的时候如果遇到state为2,则字体变色,并且输出完之后,fre中所有的state==0,pro中所有的state==1
arrangeStart(pro);
if(fit==1)
arrangeSmaller(fre);
if(fit==2)
arrangeBigger(fre);
if(fit==3)
arrangeStart(fre);
Green();
cout<<"============================"<cout<<"Processinformation:
"<cout<<"namestartsize"<Node*p=pro.head->next;
if(p==NULL)
cout<<"NULL"<while(p!
=NULL)
{
if(p->state==2)//==================================================
{
Yellow();
cout<name<start<size<p->stat