2. 鄰近適應 (循環首次適應)NF
從上一次 查找結束的位置 開始查找
-
流程圖 (參考:https://blog.csdn.net/acm_yuuji/article/details/50410483)

-
運行結果


-----java 代碼 ----
package operate2;
import java.util.*;
/** * NF 循環首次適應算法 * @author ymj * @Date: 2019/12/24 16:18 */
public class NF {
static Scanner cin = new Scanner(System.in);
/** 數據結構 空閑分區表項*/
static class Free {
int id; // 分區號
int start; // 起始地址
int capacity; // 分區大小
int status = 0; // 0 表示空閑
Free (int id, int start, int capacity){
this.id = id;
this.start = start;
this.capacity = capacity;
}
}
static int zoneId = 1; // 分區號遞增
/** 空閑分區表 */
static LinkedList<Free> LinkedFree = new LinkedList<Free>();
static int size;
/** 顯示當前內存狀態 */
public static void showState(){
System.out.println("---內存狀態---");
System.out.println("分區號 分區大小 分區始址 狀態");
for (Free free: LinkedFree) {
if(free.status == 0) { // 空閑
System.out.printf("%d\t\t %d\t\t %d\t 空閑\n",free.id, free.capacity, free.start);
} else {
System.out.printf("%d\t\t %d\t\t %d\t 占用\n",free.id,free.capacity, free.start);
}
}
System.out.println("---end---");
}
/** 初始化內存狀態 */
public static void initMemory(){
size = cin.nextInt();
Free temp = new Free(zoneId++, 100, size);
LinkedFree.add(temp); // 分區表添加元素
linkedList.add(temp); // 向空閑分區鏈表添加元素
lastPoint = temp;
showState();
}
/** 釋放內存*/
public static void release() {
Collections.sort(LinkedFree, (o1, o2) -> o1.start - o2.start);
System.out.println("輸入要釋放的分區號");
int id = cin.nextInt();
// 這里判斷 分區號是否合法的算法 省略······
// 默認 合法
Iterator<Free> iterator = LinkedFree.iterator();
int index = 0; // 要移除的分區號 下標
int index2 = -1; // 要合並的分區號
while (iterator.hasNext()) {
Free p = iterator.next();
index = LinkedFree.indexOf(p);
if(p.id == id){ // 找到此分區
Free free1 = null, free3 = null;
if(index - 1 >= 0){ //前面有分區
if (LinkedFree.get(index - 1).status == 0){ // 前 是空閑分區
free1 = LinkedFree.get(index - 1);
}
}
if(index + 1 < LinkedFree.size()) { // 后面有分區
if (LinkedFree.get(index + 1).status == 0){ // 后 是空閑分區
free3 = LinkedFree.get(index + 1);
}
}
if (free1 != null && free3 != null) { //合並前后分區
free1.capacity += p.capacity + free3.capacity;
index2 = index;
iterator.remove();
linkedList.remove(free3); // 空閑分區鏈刪除元素
}else if (free1 != null && free3 == null) { // 合並前面分區
free1.capacity += p.capacity;
iterator.remove();
}else if (free1 == null && free3 != null) { // 合並后面分區
free3.capacity += p.capacity;
free3.start -= p.capacity;
iterator.remove();
}else { // 不需要合並
p.status = 0; // 忙碌 變為空閑
int index22 = 0; // 要插入的位置
for (Free free : linkedList) { // 空閑分區鏈插入元素
if(free.start > p.start) {
index22 = linkedList.indexOf(free);
break;
}
}
linkedList.add(index22, p);
}
}
}
if (index2 != -1) {
LinkedFree.remove(index2); // 刪除合並的內存塊信息
}
}
/** 空閑分區鏈 */
static LinkedList<Free> linkedList = new LinkedList<>();
/** 指向上一次查找結束位置 的指針 */
static Free lastPoint;
/** NF 算法 */
public static void allocation() {
System.out.println("輸入申請空間大小: ");
int applySize = cin.nextInt();
Free temp = null; // 要分配的分區
Free point = lastPoint;
boolean flag = false;
while (point != lastPoint || flag == false) {
if(point.capacity >= applySize) { // 內存充裕
temp = new Free(zoneId++, point.start, applySize);
temp.status = 1;
point.capacity -= applySize;
point.start += applySize;
if (point.capacity == 0) { // 空間全部分配
LinkedFree.remove(point);
}
break;
}else {
int index = linkedList.indexOf(point);
if(index + 1 < linkedList.size()) {
point = linkedList.get(index + 1);
}else {
point = linkedList.getFirst();
}
}
flag = true;
}
if (point != lastPoint || flag == false) {
LinkedFree.add(temp);
Collections.sort(LinkedFree, (o1, o2) -> o1.start - o2.start);
showState();
}
}
/** 打印空閑分區鏈 */
public static void printLinkedList() {
System.out.println("----空閑分區鏈-----");
for (Free f : linkedList) {
System.out.printf("<分區號: %d >--", f.id);
}
System.out.printf("\n---------\n");
}
public static void main(String[] args) {
System.out.println("循環首次");
System.out.println("初始內存大小, 默認起始地址為100");
initMemory();
while(true) {
System.out.println("****1.申請內存 2.釋放內存 3.退出****");
int choice = cin.nextInt();
switch (choice) {
case 1:
allocation();
printLinkedList();
break;
case 2:
release();
showState();
printLinkedList();
break;
case 3: showState();
return;
}
}
}
}
