最佳适应算法 BF(Best Fit)
◼ 基本思想:BF 的空闲分区表(或空闲分区链)按空闲区大小的升序方式组织。分配时,按空闲分区表(或空闲分区链)的先后次序,从头查找,找到符合要求的第一个分区。就说明它是最适合的(即最佳的)。大的空闲区可以被保留下来。
代码:
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
//#define NULL 0
typedef struct table
{
int address; /*存储分区起始地址*/
int length; /*存储分区长度*/
int flag; /*存储分区标志,0 为空闲,1 为被作业占据*/
char name[10]; /*当 flag==1 时存储分区占用标志作业名,否则存储空 nil*/
struct table *next;
} node;
bool success; /*分配成功与否的标志*/
node *insertaddress(node *head, node *p)
/*按照“地址递增方式”将 p 结点插入链表相应位置*/
{
node *q=(node*)malloc(sizeof(node));
node *pre=(node*)malloc(sizeof(node));
q=head->next;
if(!q){
head->next=p;
p->next=NULL;
return head;
}
pre=head;
while(q){
if(q->address > p->address){
pre->next=p;
p->next=q;
return head;
}
else{
pre=q;
q=q->next;
}
}
if(!q){
pre->next=p;
p->next=NULL;
}
return head;
}
node *insertlength(node *head, node *p)
/*按照“空闲区大小递增方式”将 p 结点插入链表相应位置*/
{
node *q=(node*)malloc(sizeof(node));
node *pre=(node*)malloc(sizeof(node));
q=head->next;
if(!q){
head->next=p;
p->next=NULL;
return head;
}
pre=head;
while(q){
if(q->length > p->length){
pre->next=p;
p->next=q;
return head;
}
else{
pre=q;
q=q->next;
}
}
if(!q){
pre->next=p;
p->next=NULL;
}
return head;
}
node *creat() /*建立分配分区表(flag==1)或空闲分区表(flag==0)*/
{
node *head=(node*)malloc(sizeof(node));
head->next=NULL;
node *p=(node*)malloc(sizeof(node));
printf("input:address,length,flag(0 or 1),name[10],当 length == -1 时结束:\n");
scanf("%d%d%d",&p->address,&p->length,&p->flag);
getchar();
scanf("%s",p->name);
while(p->length != -1){
if(p->flag==1){
head=insertaddress(head, p);
}
else{
head=insertlength(head, p);
}
p=(node*)malloc(sizeof(node));
scanf("%d%d%d",&p->address,&p->length,&p->flag);
getchar();
scanf("%s",p->name);
}
return head;
}
int distribute(node *freehead, node *distributedhead, node *work)
/*在空闲分区表中找出首次合适 work 的分区,同时修改空闲分区表和分配分区表*/
{
node *r=(node*)malloc(sizeof(node));
node *s=(node*)malloc(sizeof(node));
node *q=(node*)malloc(sizeof(node));
node *t=(node*)malloc(sizeof(node));
s=freehead->next;
q=freehead;
while(s){
if(s->length >= work->length){
r->address=s->address;
r->length=work->length;
r->flag=1;
for(int i=0; i<10; i++)
r->name[i] = work->name[i];
distributedhead=insertaddress(distributedhead,r);
if(s->length == work->length)
q->next=s->next;
else{
t->address=s->address+work->length;
t->length=s->length-work->length;
t->flag=0;
t->name[0]='n';
t->name[1]='u';
t->name[2]='i';
t->name[3]='l';
q->next=s->next;
freehead=insertlength(freehead,t);
}
return 1;
}
else{
q=s;
s=s->next;
}
}
if(!s){
printf("distributing is not successful!!\nPlease input again\n");
}
return 0;
}
void print (node *head) /*输出链表*/
{
node *p=(node*)malloc(sizeof(node));
p=head->next;
while(p){
printf("%d,%d,%d,%s\n",p->address,p->length,p->flag,p->name);
p=p->next;
}
}
int main()
{
int a;
struct table *dtable,*ftable;
node *work=(node*)malloc(sizeof(node));
char workn[10];
dtable=creat(); /*dtable 输入已分配情况表*/
printf("\nThe distributed table is:\n");
print(dtable);
printf("\n");
ftable=creat(); /*ftable 输入未分配情况表*/
printf("\nThe free table is:\n");
print(ftable);
printf("\n");
/*以下模拟逐个内存申请过程*/
printf("input(当a = -1时结束):\n");
printf("The length of worked job is:");
scanf("%d",&a);
printf("\n");
//getchar();
printf("The name of worked job is:");
scanf("%s",workn);
for(int i=0; i<10; i++){
work->name[i] = workn[i];
}
work->length=a;
while(a!=-1){
if(distribute(ftable, dtable, work)){
printf("distributing is successful!\n");
printf("\nThe free table is:\n");
print(ftable);
printf("\nThe distributed table is:\n");
print(dtable);
printf("\n");
}
work=(node*)malloc(sizeof(node));
printf("The length of worked job is:");
scanf("%d",&a);
printf("\n");
//getchar();
printf("The name of worked job is:");
scanf("%s",workn);
for(int i=0; i<10; i++){
work->name[i] = workn[i];
}
work->length=a;
}
return 0;
}
测试数据:
/*0 60 1 OS
60 40 1 task1
132 18 1 task2
160 40 1 task3
205 15 1 task4
438 92 1 task5
626 174 1 task6
0 -1 1 0*/
/*100 32 0 nuil
150 10 0 nuil
200 5 0 nuil
220 218 0 nuil
530 96 0 nuil
0 -1 0 0*/
终于写完了!!!