首次适应算法从空闲分区表的第一个表目起查找该表,把最早可以知足要求的空闲区分配给做业,这种方法目的在于减小查找时间。为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到高进行排序。该算法优先使用低址部分空闲区,在低址空间形成许多小的空闲区,在高地址空间保留大的空闲区。算法
最佳适应算法是指从所有空闲区中找出能知足做业要求且大小最小的空闲分区的一种计算方法,这种方法能使碎片尽可能小。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