兩種算法
-
首次適應
首次適應算法從空閑分區表的第一個表目起查找該表,把最先能夠滿足要求的空閑區分配給作業,這種方法目的在於減少查找時間。為適應這種算法,空閑分區表(空閑區鏈)中的空閑分區要按地址由低到高進行排序。該算法優先使用低址部分空閑區,在低址空間造成許多小的空閑區,在高地址空間保留大的空閑區。
-
最佳適應
最佳適應算法是指從全部空閑區中找出能滿足作業要求且大小最小的空閑分區的一種計算方法,這種方法能使碎片盡量小。
程序代碼
#include <stdio.h>
#include <stdlib.h>
struct area
{
int id; // 編號
int addr_front; //首地址
int size; //分區大小
int flag; //分配標志
struct area *front; //上一分區
struct area *next; //下一分區
};
typedef struct area partion;
partion *head = NULL; //分區隊列頭節點
int need; //需求
int choice = 1; //操作選項
partion *createPartion(int id, int addr_front, int size, int flag); //生成一個節點
void inputNeed(); //輸入需求量
void assign(partion *ptr, int need); //分配分區
void first_fit(); //首次適應算法
void best_fit(); //最佳適應算法
void showMemoryInfo(); //打印分區分配狀況
void recovery(); //分區回收
void changeIdValue(partion *ptr, int delta); //改變從ptr開始所有節點的id值
int main(void)
{
head = createPartion(0, 0, 200, 0);
while (choice != 0)
{
puts("-------------------\nchoose operation:\n1:First_Fit;\n2:Best_Fit;\n3:recovery;\n4:showinformation;\n0:quit......\n-------------------");
scanf("%d", &choice);
switch (choice)
{
case 1:
inputNeed();
first_fit();
break;
case 2:
inputNeed();
best_fit();
break;
case 3:
recovery();
break;
case 4:
showMemoryInfo();
break;
case 0:
puts("byebye");
break;
default:
break;
}
}
system("pause");
return 0;
}
partion *createPartion(int id, int addr_front, int size, int flag)
{
partion *p = (partion *)malloc(sizeof(partion));
p->id = id;
p->addr_front = addr_front;
p->size = size;
p->flag = flag;
p->front = NULL;
p->next = NULL;
return p;
}
void inputNeed()
{
printf("please input the need:");
scanf("%d", &need);
}
void first_fit()
{
partion *fit = NULL;
partion *ptr = head;
while (ptr != NULL)
{
if (ptr->size >= need && ptr->flag == 0)
{
fit = ptr;
break;
}
ptr = ptr->next;
}
if (fit != NULL)
{
assign(fit, need);
printf("assigned successfully!\n");
}
else
{
puts("Sorry,there is no appropriate partion!");
free(fit);
}
}
void best_fit()
{
partion *fit = NULL;
partion *ptr = head;
int flag = 0; //flag 表示是否找到可分配的分區
while (ptr != NULL)
{
if (ptr->flag == 0 && ptr->size >= need)
{
if (flag == 0)
{
//只有遇到的第一個可分配分區回執行此操作
fit = ptr;
flag = 1;
}
else
{
//若遇到可分配且分區更小即更適合的則更新
if (ptr->size < fit->size)
{
fit = ptr;
}
}
}
ptr = ptr->next;
}
//先處理沒找到合適分區的情況
if (flag == 0)
{
puts("Sorry,there is no appropriate partion!");
free(fit);
return;
}
//找到則分配
assign(fit, need);
puts("assigned successfully!");
}
void showMemoryInfo()
{
partion *ptr = head;
puts("\n\n---------------------------------------------");
puts("Here is the information of memory:");
puts("---------------------------------------------");
while (ptr != NULL)
{
printf("id:%21d%10c\nfront address:%10d%10c\n", ptr->id, '|', ptr->addr_front, '|');
printf("partion size:%11d%10c\n", ptr->size, '|');
printf("status:%17s%10c\n", ptr->flag == 0 ? "available" : "busy", '|');
puts("----------------------------------");
ptr = ptr->next;
}
puts("---------------------------------------------\n\n");
}
void assign(partion *ptr, int need)
{
if (need == ptr->size)
{
ptr->flag = 1;
return;
}
partion *assigned = createPartion(ptr->id, ptr->addr_front, need, 1);
assigned->next = ptr;
assigned->front = ptr->front;
changeIdValue(ptr, 1);
ptr->addr_front += need;
ptr->size -= need;
if (ptr->front != NULL)
{
ptr->front->next = assigned;
}
else
{
head = assigned;
}
ptr->front = assigned;
}
void recovery()
{
printf("please input the id to recovery:");
int id, flag = 0;
scanf("%d", &id);
partion *ptr = head;
while (ptr != NULL)
{
if (id == ptr->id)
{
flag = 1;
break;
}
ptr = ptr->next;
}
if (flag == 0)
{
puts("No such partion!");
return;
}
if (ptr->flag == 0)
{
puts("This partion is not busy!");
return;
}
if (ptr->front == NULL)
{
//第一個分區
if (ptr->next == NULL || ptr->next->flag == 1)
{
//后面不空或后面沒有
ptr->flag = 0;
return;
}
if (ptr->next->flag == 0)
{
//后面空
ptr->size += ptr->next->size;
ptr->flag = 0;
if (ptr->next->next != NULL)
{
ptr->next->next->front = ptr;
}
ptr->next = ptr->next->next;
free(ptr->next);
return;
}
}
if (ptr->next == NULL)
{
//最后一個分區
if (ptr->front == NULL || ptr->front->flag == 1)
{
//前面不空或者前沒有
ptr->flag = 0;
return;
}
if (ptr->front->flag == 0)
{
//前面為空
ptr->front->size += ptr->size;
ptr->front->next = NULL;
free(ptr);
return;
}
}
if (ptr->front->flag == 0 && ptr->next->flag == 0)
{
//上下都空
ptr->front->size += ptr->size + ptr->next->size;
ptr->front->next = ptr->next->next;
if (ptr->next->next != NULL)
{
ptr->next->next->front = ptr->front;
}
changeIdValue(ptr->front->next, -2); //更改id
free(ptr->next);
free(ptr);
return;
}
if (ptr->front->flag == 0 && ptr->next->flag == 1)
{
//上空下不空
ptr->front->size += ptr->size;
ptr->front->next = ptr->next;
ptr->next->front = ptr->front;
changeIdValue(ptr->front->next, -1);
free(ptr);
return;
}
if (ptr->front->flag == 1 && ptr->next->flag == 0)
{
//上不空下空
ptr->size += ptr->next->size;
if (ptr->next->next != NULL)
{
ptr->next->next->front = ptr;
}
partion *p_next = ptr->next; //保存一下下方為空的那個分區,以便一會釋放
ptr->next = ptr->next->next;
ptr->flag = 0;
changeIdValue(ptr->next, -1);
free(p_next);
return;
}
if (ptr->front->flag == 1 && ptr->next->flag == 1)
{
//上下都不空
ptr->flag = 0;
return;
}
}
void changeIdValue(partion *ptr, int delta)
{
while (ptr != NULL)
{
ptr->id += delta;
ptr = ptr->next;
}
}
運行截圖
-
首次適應
-
最佳適應
-
內存回收
如有錯誤歡迎指正