日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

【操作系统】分区分配算法(首次适应算法、最佳适应算法)C语言

發布時間:2023/12/16 windows 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【操作系统】分区分配算法(首次适应算法、最佳适应算法)C语言 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【操作系統】分區分配算法 (首次適應算法、最佳適應算法)(C語言實現)

(編碼水平較菜,寫博客也只是為了個人知識的總結和督促自己學習,如果有錯誤,希望可以指出)

今天測試,發現一點問題:
1.最佳插入算法:對于插入的時候忘記修改temp.next.front的指向
2.回收頭節點的時候現在多了一種判斷。判斷頭節點的下一個是否為空。對如果不為空而且后面的空閑的話,做出了處理。原來則沒有這一情況。

3.首次適應算法在 第一個分區未分配,第二個分區已分配時沒有改變 temp_next->front 的指向,所以導致了后續的一些小問題,已經修改。

1.動態分區分配算法:

為了實現動態分區分配,通常將系統中的空閑分區鏈接成一個鏈。所謂順序查找是指依次搜索空閑分區鏈上的空閑分區,去尋找一個大小能滿足要求的分區。 --------計算機操作系統(第四版)

2.動態分區算法主要包括四種:

(1).首次適應算法(first fit,FF):

要求,空閑分區鏈以地址遞增的順序鏈接。每次從鏈首開始,直到找到第一個能滿足要求的空閑分區為止。
簡單來說,就是,每次都從第一個開始順序查找,找到一塊區域可以滿足要求的。

優點:優先利用內存中低址部分的空閑分區,從而保留了高址部分的大空閑區,這為以后到達的大作業分配大的內存空間創造了條件。
缺點:低址部分不斷被劃分,會留下許多難以利用的,很小的空閑分區,稱為碎片。而每次查找又都是從低址部分開始的,這無疑又會增加查找可用空閑分區時的開銷。

(2).循環首次適應算法(next fit,NF):

與FF算法區別就是,不是每次都從首次開始,而是從上次找到的空閑分區的下一個空閑分區開始。(第一次查找的話也是從首頁開始)。

特點:能使內存中的空閑區分布得較均勻。

(3).最佳適應算法(best,BF):

將所有空閑分區按照空閑分區容量大小從小到大的順序連接起來,形成一個空閑分區鏈。
即,每次都是找空間容量不但可以滿足要求的空閑區,而且該空閑分區的容量還要最接近要求的容量大小。

優點:每次分配給文件的都是最合適該文件大小的分區。
缺點:內存中留下許多難以利用的小的空閑區(外碎片)。

(4).最壞適應算法(worst,WF):

與BF算法相反,WF算法是按照空閑分區容量從大到小的順序連接起來的,而且每次找空閑分區的時候也是按照空閑分區容量最大的。

特點:盡可能的分配大的分區。
缺點:使得內存缺乏大分區,可能使得后續到來的大作業無法裝入內存。

3.主要實現的是首次適應算法和最佳適應算法。

運行截圖:




4.就不一一截圖了,還沒有發現什么問題。如果有人發現了,希望可以指正一下,不勝感激

5.代碼

#include<stdio.h> #include<stdlib.h>typedef struct lei_item //表示空閑分區表中的表箱 {int id; //假如 id 為-1,表示此分區時一個空閑分區。int base; //指向分區的首地址int size; //表示分區大小int status; //表示此分區是否已經分配 0表示空閑 1表示已經分配 }Item; typedef Item datatype;typedef struct lei_list {datatype* node; //表示一個datatype類型的鏈表的結點struct lei_list* front;struct lei_list* next; }List;#define Max 640 int memory = Max; //定義可用內存空間為640List init(){ //初始化一個鏈表;List list;list.node = (datatype *)malloc(sizeof(datatype));list.node->base = 0;list.node->id = -1; //-1表示是空閑分區list.node->size = memory;list.node->status = 0; list.front = list.next = NULL;return list; }datatype* input(){ //初始化打算申請的內存分區節點datatype* item = (datatype *)malloc(sizeof(datatype));printf("請輸入作業號:");scanf("%d",&item->id);printf("請輸入所需要的內存的大小:");scanf("%d",&item->size);item->status = 0;return item; } void Momery_state(List *list){List* temp = list;printf("-----------------------------------\n");printf("內存分配狀況\n");printf("-----------------------------------\n");while (temp){if(temp->node->status == 0 && temp->node->id == -1){printf("分區號:FREE\n");printf("起始地址:%d\n",temp->node->base);printf("內存大小:%d\n",temp->node->size);printf("分區狀態:空閑\n");}else{printf("分區號:%d\t起始地址:%d\n",temp->node->id,temp->node->base);printf("內存大小:%d\n",temp->node->size);printf("分區狀態:已分配\n");}printf("-----------------------------------\n");temp = temp->next;}}int First_fit(List *list){datatype* item = input();List* temp = list; //定義一個臨時變量list* ,指向listwhile (temp){if(temp->node->status == 0 && temp->node->size > item->size){ //如果此前的分區未分配,,并且分區大小大于 請求分配的大小 那么此時就可以進行分配List *front = temp->front; //存儲當前未分配分區的 上一個分區地址List *next = temp->next; //存儲當前未分配分區的 下一個分區地址 int base = temp->node->base; //記錄未分配當前分區的首地址datatype* new_node = (datatype*)malloc(sizeof(datatype)); // 多余出來的部分要新建立一個分區new_node->id = -1; //然后需要對這個新的分區進行一些信息的設置new_node->size = temp->node->size - item->size; //新分區的大小 等于 還未分配的時的分區大小 - 請求分配的結點的大小 temp->node = item; //對請求分配的分區結點進行分配temp->node->status = 1;new_node->status = 0;new_node->base = base + temp->node->size; //新建立分區的首地址是 請求分配的分區的首地址 + 請求分配的分區的大小List* temp_next = (List*)malloc(sizeof(List)); //臨時節點 (申請一個新的鏈表節點 表示下一個分區) 并且進行初始化temp_next->node = new_node; //保存下一個的分區的信息temp_next->front = temp_next->next = NULL; if(front == NULL && next == NULL){ //如果 front和next節點都是空,表明它是第一次分配分區temp->node->base = 0; //初始化首地址temp->next = temp_next; temp_next->front = temp;}if(front == NULL && next != NULL){ //在第一個分區中插入新的分區temp->node->base = 0;temp->node->status = 1;temp_next->front = temp;temp_next->next = temp->next;temp->next = temp_next;}if(front != NULL){ //表明不是第一次分配節點,此時需要在中間插入下一個節點temp->node->base = temp->front->node->base+temp->front->node->size; //初始化首地址temp_next->next = temp->next; //保證新插入的節點會記錄原先節點的下一個節點的首地址temp_next->front = temp; // 首尾都需要保證temp->next = temp_next; //最后讓所申請的分區節點的下一個節點指向 我們剛剛建立的臨時節點}return 1;} else if(temp->node->status == 0 && temp->node->size == item->size){item->base = temp->front->node->base+temp->front->node->size; //新插入分區的首地址 等于上一個分區的 首地址+分區的大小item->status = 1; //表示已經分配temp->node = item;return 1;}else{temp = temp->next;continue;}temp = temp->next;}return 0; }int Momory_recycle(List *list){List* temp = list; //申請一個鏈表節點 指向list 的頭節點int number; //用于存放要釋放的節點的分區號printf("請輸入需要回收的ID號:");scanf("%d",&number);while (temp){ if(temp->node->id == number) //首先找到 節點id = number 的節點,然后分四種情況討論 { // 一、 要回收的是第一個結點if(temp->front == NULL){temp->node->status = 0;temp->node->id = -1;if(temp->next == NULL){temp->node->size = temp->node->size + temp->next->node->size;temp->next = temp->next;return 1;}if(temp->next->node->id == -1 && temp->next->node->status == 0){List* next = temp->next;// 此時來判斷 temp->next 是否是系統的最后一個結點// 此時只將當前節點 和下一個結點合并就可以了//即 首地址不變, 分區狀態 和 分區id進行變化 temp->node->size = temp->node->size + next->node->size;temp->node->status = 0;temp->node->id = -1;temp->next = next->next;if(next->next == NULL){free(next);return 1;}//如果不是最后一個結點的話就會多一個步驟// 讓 next->next->front 指向上一個結點else{next->next->front = temp;free(next); return 1;} }return 1;}//二、 前后都沒有空閑的分區//最簡單, 直接改變 分區的 id 和 分區的狀態就可以了。// 如果回收第一個分區的話 必須要先進行處理,如果不先進行處理 ,判斷 temp->front->node->id != -1 會報一個段錯誤。因為temp-》front 此時指向的是null if(temp->front->node->id != -1 && temp->front->node->status != 0 && temp->next->node->id != -1 && temp->next->node->status != 0){temp->node->status = 0;temp->node->id = -1;return 1;}//三、要回收的節點 前面和后面都是空閑的// 將三個空閑區合并到一起,起始地址為前面的分區的起始地址, 大小為三個空閑區大小之和//還需要做一個判斷,如果if(temp->front->node->id == -1 && temp->front->node->status == 0 && temp->next->node->id == -1 && temp->next->node->status == 0){List* front = temp->front;List* next = temp->next;front->node->size = front->node->size + temp->node->size + next->node->size; front->next = next->next;if(next->next == NULL){free(temp);return 1;}//如果不是最后一個結點的話就會多一個步驟// 讓 next->next->front 指向上一個結點else{next->next->front = front;free(temp); return 1;} return 1;}// 四、 要回收的節點 前面的節點是空閑的//合并后的分區起始地址為前一個結點, 分區大小為前一個節點 與 當前節點之和。if(temp->front->node->id == -1 && temp->front->node->status == 0){List* front = temp->front;front->next = temp->next;temp->next->front = front;front->node->size += temp->node->size;free(temp);return 1;}//五、 要回收的節點 后面的額節點是空閑的//合并后的分區首地址為當前節點 , 分區大小為當前節點 與 當前節點的下一個結點大小之和。// 這個需要多一個步驟, 改變分區的 id 和 分區的狀態。// 還要注意一點: 當要回收的空間是和 系統最后的空閑區相鄰時 , temp->next->next 指向的是null;if(temp->next->node->id == -1 && temp->next->node->status == 0){List* next = temp->next;// 此時來判斷 temp->next 是否是系統的最后一個結點// 此時只將當前節點 和下一個結點合并就可以了//即 首地址不變, 分區狀態 和 分區id進行變化 temp->node->size = temp->node->size + next->node->size;temp->node->status = 0;temp->node->id = -1;temp->next = next->next;if(next->next == NULL){free(next);return 1;}//如果不是最后一個結點的話就會多一個步驟// 讓 next->next->front 指向上一個結點else{next->next->front = temp;free(next); return 1;} }}temp = temp->next;}return 0;}int Best_fit(List *list){int min = 0; //記錄 最小分區的結點的大小int base_min = 0; //記錄 最小節點的結點的起始地址List* temp = list; datatype* item = input(); // 要對 item 的 起始地址 和 分配狀態進行初始化while (temp){//如果分區未分配 就要進行 比較操作, 并且記錄差值 和 分區的id號if(temp->node->status == 0 && temp->node->id == -1&& temp->node->size > item->size){if(min == 0){ //加入min為0 表示還未找到一個可以分配的分區min = temp->node->size;base_min = temp->node->base;}else{if(temp->node->size < min){ // 找到一個之后,需要找出最小的分區 也就是它的 size最小。min = temp->node->size;base_min = temp->node->base;}}}if(temp->node->status == 0 && temp->node->id == -1 && temp->node->size == item->size){int base = temp->node->base;temp->node = item;temp->node->status = 1;temp->node->base = base;return 1;}temp = temp->next;}//因為可能沒有任何一個空間可以滿足要求需要做一個判斷處理 temp = list;while (temp){if(temp->node->base == base_min){datatype* temp_node = (datatype*)malloc(sizeof(datatype)); //會有多余的空間多出來 所以需要在建立一個結點插入到鏈表中temp_node->id = -1;temp_node->status = 0;temp_node->base = base_min + item->size;temp_node->size = temp->node->size - item->size;temp->node = item; //對item進行完整的初始化temp->node->base = base_min;temp->node->status = 1;List* temp_list_node = (List*)malloc(sizeof(List)); //新申請一個 鏈表的結點 并且初始化temp_list_node->node = temp_node;temp_list_node->front = temp;temp_list_node->next = temp->next;if(temp->next != NULL){temp->next->front = temp_list_node;}temp->next = temp_list_node;return 1;}temp = temp->next;}}int main(){printf("分區模擬\n");List list = init();int select;int insert_state,recycle_state;int insert_state_best;do{printf("請輸入要進行的操作\n");printf("1-首次適應算法, 2-最佳適應算法, 3-內存回收, 4-顯示內存狀況, 5-退出\n");scanf("%d",&select);switch (select){case 1: // 1. 首次適應算法insert_state = First_fit(&list);if(insert_state == 0){printf("分配失敗\n");}else {printf("分配成功!\n");} break;case 2: // 2. 最佳適應算法insert_state_best = Best_fit(&list);if(insert_state_best == 1){printf("分配成功\n");} else {printf("分配失敗\n");} break;case 3: //3.內存回收recycle_state = Momory_recycle(&list);if(recycle_state == 1){printf("回收成功!\n");}else{printf("回收失敗\n");}break;case 4: //4.顯示內存狀況Momery_state(&list);break; }} while (select != 5);system("pause"); }

總結

以上是生活随笔為你收集整理的【操作系统】分区分配算法(首次适应算法、最佳适应算法)C语言的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。