- 1.算法简介
首次适应算法(First Fit)
算法思想:该算法从空闲分区链首开始查找,直至找到一个能满足其大小要求的空闲分区为止。然后再按照作业的大小,从该分区中划出一块内存分配给请求者,余下的空闲分区仍留在空闲分区链中。
特点:该算法倾向于使用内存中低地址部分的空闲区,在高地址部分的空闲区很少被利用,从而保留了高地址部分的大空闲区。显然为以后到达的大作业分配大的内存空间创造了条件。
缺点:低地址部分不断被划分,留下许多难以利用、很小的空闲区,而每次查找又都从低地址部分开始,会增加查找的开销。
- 2.代码模拟实现
#include<bits/stdc++.h>
using namespace std;
int const total=200; //内存总数
int const begin_address = 20;//初次分配起始地址
struct Block
{
int addr; //块的起始地址
int size; // 块的大小
int flag; //块的分配状态 1:代表已分配 0:代表未分配;
}block[100];//从1开始
int counts=0; //块的个数,初值为0,分配一个则加1,减少一个则减1
void display() //显示所有块的数据
{
for(int i=1;i<=counts;i++)
{
cout<<"块号:"<<i<<" 起始地址:"<<block[i].addr<<" 大小:"<<block[i].size;
if(block[i].flag==0)
{
cout<<" 分配状态:未分配"<<endl;
}else{
cout<<" 分配状态:已分配"<<endl;
}
}
cout<<endl;
}
void First_Fit()//首次适用算法
{
int size;
cout<<"请输入要调入内存的进程大小"<<endl;
cin>>size;
for(int i=1;i<=counts;i++)
{
if(block[i].flag==0&&block[i].size>=size)
{
if(block[i].size==size)
{
block[i].flag=1;
}else
{
counts++;
for(int j=counts;j>i+1;i--)//将第i块后面的块整体后移
{
block[j]=block[j-1];
}
block[i+1].addr=block[i].addr+size;//初始化新创建的块
block[i+1].size=block[i].size-size;
block[i+1].flag=0;
block[i].flag=1;
block[i].size=size;
}
break;
}
}
}
void Out()//进程调出模块
{
int num;
cout<<"请输入要调出内存的块号"<<endl;
cin>>num;
if(block[num].flag==0)
{
cout<<"该内存是空闲的,无需再调出"<<endl;
}else
{
block[num].flag=0;
if(block[num+1].flag==0&&num<counts)//如果下一块空闲则合并
{
block[num].size=block[num].size+block[num+1].size;
for(int i=num+2;i<=counts;i++)
{
block[i-1]=block[i];
}
counts--;
}
if(block[num-1].flag==0&&num!=1)//如果上一块空闲则合并
{
block[num-1].size=block[num].size+block[num-1].size;
for(int i=num+1;i<=counts;i++)
{
block[i-1]=block[i];
}
counts--;
}
}
}
void Menu()//菜单功能函数
{
int exit_flag=0;//菜单循环控制标识
int select;
while(exit_flag==0)
{
cout<<"请输入相应操作:"<<endl;
cout<<"1.进程进入内存"<<endl;
cout<<"2.进程退出内存"<<endl;
cout<<"3.显示当前状态"<<endl;
cout<<"4.退出"<<endl;
cin>>select;
switch(select)
{
case 1:
First_Fit();
break;
case 2:
Out();
break;
case 3:
display();
break;
case 4:
exit_flag=1;
break;
default:
cout<<"输入异常,请重试"<<endl;
}
}
}
int main()
{
block[1].addr=begin_address;//第一块初始化
block[1].flag=0;
block[1].size=total-begin_address;
counts++;
display();//显示初始状态
Menu();//功能函数
return 0;
}
- 3.运行结果