NF 循環首次適應算法 (java)


					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;
            }
        }

    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM