下次适应(Next Fit)算法 | 存储分配 | Java实现(详细注释)

写在前面

欢迎讨论~


问题描述

题目:下次适应(Next Fit)存储分配算法
要求:设计存储资源数据结构arrayof(m_size,m_addr),编写两个函数:(1) malloc(int size), 申请一个长度为size的空闲存储区,返回区域起始地址,不能满足时返回0;(2) mfree(int size, int aa), size为释放区域大小,aa为起始地址。
说明:(1) 申请时有两种情况:按下次适应找到的空闲区域大小与size相同;空闲区域大于size. (2) 释放时有四种情况:释放区域与前面空闲区相邻,与后面空闲区相邻,与前后空闲区均相邻,与前后空闲区均不相邻。
提示:需要设一个静态变量static p, 指向下次分配时的起始查找位置,注意表的首尾相连。


Java实现

ArrayOf 保存空闲空间的数据结构
Disk模拟内存实现nextFit算法
Main主函数和测试数据


ArrayOf

/**
 * 保存你存剩余空间的数据结构
 * m_addr 剩余空间的首地址
 * m_size 剩余空间的大小
 */
public class ArrayOf {
    public int m_addr;/*剩余空间的首地址*/
    public int m_size;/*剩余空间的大小*/

    @Override
    public String toString() {
        return "{" +
                 + m_addr +
                "," + m_size +
                '}';
    }
}


Disk

import java.util.Arrays;

/**
 * 模拟内存,实现申请释放空间的算法
 * (1) 申请时有两种情况:按下次适应找到的空闲区域大小与size相同;空闲区域大于size.
 * (2) 释放时有四种情况:释放区域与前面空闲区相邻,
 *     与后面空闲区相邻,与前后空闲区均相邻,与前后空闲区均不相邻。
 */
public class Disk {
    int arraySize=10;/*arrayOf数组的大小*/
    private ArrayOf[] arrayOf=new ArrayOf[arraySize];/*保存内存剩余的空间*/
    int p;/*下次查找位置,Java中无指针*/

    Disk(){
        p=0;
        for (int i=0;i<arraySize;i++)
        {
            arrayOf[i]=new ArrayOf();
        }
        arrayOf[0].m_size=10000;
        arrayOf[0].m_addr=200;
        arrayOf[1].m_size=0;
        System.out.println("初始状态:"+outArray());
    }
    /**
     *  申请一个长度为size的空闲存储区,返回区域起始地址,不能满足时返回0
     * @param size 申请空间大小
     * @return 不能满足时返回0
     */
    public int malloc(int size){
        /*申请空间需要更新next指针,ArrayOf表保存了存储区中的空闲区域(首地址和大小),首先根据ArrayOf表找到合适的空间,然后更新ArrayOf表*/
        
        int new_p=p;
        int now_p;
        int address;
        for(now_p=new_p;arrayOf[now_p].m_size!=0&&arrayOf[now_p].m_size<size;now_p++);
        if (arrayOf[new_p].m_size==0)
        {
            /*说明找到尾了也没有找到,从头开始找*/
            for(now_p=0;now_p<new_p&&arrayOf[now_p].m_size<size;now_p++);
        }
        if(arrayOf[now_p].m_size<size)
        {
            /*说明没有找到合适的空间*/
            System.out.println("申请空间:"+size+" 未申请到空间"+" 申请后空间分布为:"+outArray());
            return 0;
        }
        else {
            /*说明找到合适空间*/

            /*空闲区域大于size,直接减掉就好了*/
            address=arrayOf[now_p].m_addr;
            arrayOf[now_p].m_addr+=size;
            arrayOf[now_p].m_size-=size;
            /*更新p*/
            p=now_p;
            if(arrayOf[now_p].m_size==0)
            {
                /*空闲区域大小与size相同,覆盖区域*/
                do {
                    now_p++;
                    arrayOf[now_p-1].m_size=arrayOf[now_p].m_size;
                    arrayOf[now_p-1].m_addr=arrayOf[now_p].m_addr;
                }while (arrayOf[now_p-1].m_size!=0);
            }
            /*返回首地址*/
            System.out.println("申请空间:"+size+" 申请到首地址:"+address+" 申请后空间分布为:"+outArray());
            return address;
        }
    }

    /**
     * @param size 释放区域大小
     * @param aa 起始地址
     */
    public void mfree(int size ,int aa){

        /*释放空间无需更新next指针,ArrayOf表保存了存储区中的空闲区域(首地址和大小),首先根据ArrayOf表找到合适的空间,然后更新ArrayOf表*/
        int size_old=size;
        int aa_old=aa;
        int new_p=p;
        int now_p;
        int t;
        for(now_p=0;arrayOf[now_p].m_size!=0&&arrayOf[now_p].m_addr<aa;now_p++);/*找到指针对应位置*/
        if(now_p==0)
        {
            /*放在首个的特殊处理,与不需要合并处理方法相同*/
            do {
                /*交换address*/
                t=arrayOf[now_p].m_addr;
                arrayOf[now_p].m_addr=aa;
                aa=t;
                /*交换size*/
                t=arrayOf[now_p].m_size;
                arrayOf[now_p].m_size=size;
                size=t;
                now_p++;
            }while (size!=0);
            arrayOf[now_p].m_size=0;
        }
        if(arrayOf[now_p-1].m_addr+arrayOf[now_p-1].m_size==aa)
        {
            /*与前面合并*/
            arrayOf[now_p-1].m_size+=size;
            if (arrayOf[now_p-1].m_addr+arrayOf[now_p-1].m_size==arrayOf[now_p].m_addr)
            {
                /*需要与后面合并*/
                arrayOf[now_p-1].m_size+=arrayOf[now_p].m_size;
                do {
                    now_p++;
                    arrayOf[now_p-1].m_size=arrayOf[now_p].m_size;
                    arrayOf[now_p-1].m_addr=arrayOf[now_p].m_addr;
                }while (arrayOf[now_p-1].m_size!=0);
            }
        }
        else if(aa+size==arrayOf[now_p].m_addr)
        {
            /*需要与后面合并*/
            arrayOf[now_p].m_addr-=size;
            arrayOf[now_p].m_size+=size;
        }
        else {
            /*不需要合并*/
            do {
                /*交换address*/
                t=arrayOf[now_p].m_addr;
                arrayOf[now_p].m_addr=aa;
                aa=t;
                /*交换size*/
                t=arrayOf[now_p].m_size;
                arrayOf[now_p].m_size=size;
                size=t;
                now_p++;
            }while (size!=0);
            arrayOf[now_p].m_size=0;
        }

        System.out.println("释放空间:"+size_old+" 释放首地址:"+aa_old+" 释放后空间分布为:"+outArray());
    }

    /**
     * 输出arrayOf数组的情况
     * @return 当前arrayOf数组的情况
     */
    private String outArray(){
        //System.out.print(Arrays.toString(arrayOf));
        return Arrays.toString(arrayOf);
    }
}


Main

/**
 * 主函数和测试数据
 */
public class Main {
    public static void main(String[] args) {
        Disk disk=new Disk();
        disk.malloc(10);/*空闲区域大于size.*/
        disk.malloc(20);
        disk.malloc(200);
        disk.malloc(50);
        disk.malloc(300);
        disk.malloc(200);
        disk.malloc(9220);
        disk.malloc(10);/*无空闲区域*/
        disk.mfree(20,210);
        disk.malloc(20);/*空闲区域大小与size相同*/

        disk.mfree(20,210);/*与前后空闲区均不相邻*/
        disk.mfree(200,780);/*与前后空闲区均不相邻*/
        disk.mfree(200,230);/*与前面相邻*/
        disk.mfree(300,480);/*与后面相邻*/
        disk.mfree(50,430);/*前后都相邻*/
    }
}


实验结果

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值