首次適應算法從空閒分區表的第一個表目起查找該表,把最早可以知足要求的空閒區分配給做業,這種方法目的在於減小查找時間。爲適應這種算法,空閒分區表(空閒區鏈)中的空閒分區要按地址由低到高進行排序。該算法優先使用低址部分空閒區,在低址空間形成許多小的空閒區,在高地址空間保留大的空閒區。算法
最佳適應算法是指從所有空閒區中找出能知足做業要求且大小最小的空閒分區的一種計算方法,這種方法能使碎片儘可能小。app
#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; } }
若有錯誤歡迎指正ui