动态分区算法(头歌实验)第1关:首次适应算法。第2关:最佳适应算法。

news2025/7/21 4:18:49

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

题目:

第1关:首次适应算法

任务描述

     假设初始状态下可用的内存空间为55MB,并有如下的请求序列: 作业1申请15MB 作业2申请30MB 作业1释放15MB 作业3分配8MB 作业4分配6MB 作业2释放30MB 请采用首次适应算法进行内存块的分配和回收,并打印出空闲内存分区链的情况

相关知识

内存分配

    空闲分区链按地址递增的顺序链接。在分配内存时,从链首开始顺序查找,直至找到一个大小能满足要求的空闲分区。然后再按照作业的大小,从该分区中划出一块内存空间,分配给请求者,余下的空闲分区仍留在空闲链中。若从链首到链尾都找不到一个能满足要求的分区,则表明系统没有足够大的内存分配给该进程,内存分配失败返回。

内存回收

    当进程运行完毕释放内存时,系统根据回收区的首址,从空闲区链(表)中找到相应的插入点,此时可能出现以下四种情况之一:

(1) 回收区与插入点的前一个空闲分区F1相邻接,此时应将回收区与插入点的前一分区合并,不必为回收分区分配新表项,而只需修改其前一分区F1的大小。

(2) 回收分区与插入点的后一空闲分区F2相邻接,此时也可将两分区合并,形成新的空闲分区,但用回收区的首址作为新空闲区的首址,大小为两者之和。

(3) 回收区同时与插入点的前、后两个分区F1和F2邻接,此时将三个分区合并,使用F1的表项和F1的首址,取消F2的表项,大小为三者之和。

(4) 回收区前后没有空闲分区。这时应为回收区单独建立一个新表项,填写回收区的首址和大小,并根据其首址插入到空闲链中的适当位置

编程要求

    空闲分区采用带头结点的双向链表来管理,主函数、链表初始化函数和打印函数已实现,只需要补充首次适应算法分配内存的函数 first_fit以及内存回收的函数recycle()即可。

bool first_fit(int id,int m_size)//使用首次适应算法给作业分配内存,id为作业号,m_size为作业大小 void recycle(int id)//回收内存,id为释放内存的作业号

代码:

#include <stdio.h>
#include <stdlib.h>
const int Max_length=55;//最大内存
struct areaNode//管理分区的结构体
{
    int ID;//分区号 
    int size;//分区大小 
    int address;//分区地址 
    int flag;//使用状态,0为未占用,1为已占用
};
typedef struct DuNode//双向链表结点
{
  struct areaNode data;//数据域 
  struct DuNode *prior;//指针域 
  struct DuNode *next;
}*DuLinkList;
DuLinkList m_head = new DuNode, m_last = new DuNode;//双向链表首尾指针
void init()//分区链表初始化
{
  m_head->prior = NULL;
  m_head->next = m_last;
  m_last->prior = m_head;
  m_last->next = NULL;
  m_head->data.size = 0;
  m_last->data.address = 0;
  m_last->data.size = Max_length;
  m_last->data.ID = 0;
  m_last->data.flag = 0;
}
void show()
{
  DuNode *p = m_head->next;//指向空闲区队列的首地址 
  printf("+++++++++++++++++++++++++++++++++++++++\n");
  while (p)
  {
    printf("分区号:");
 if (p->data.ID == 0)
   printf("FREE\n");
 else
   printf("%d\n",p->data.ID);
 printf("分区起始地址:%d\n",p->data.address);
 printf("分区大小:%d\n",p->data.size);
 printf("分区状态:");
 if (p->data.flag)
   printf("已被占用\n");
 else
   printf("空闲\n");
 printf("——————————————————\n");
 p = p->next;
  }
}
bool first_fit(int id,int m_size)//首次适应算法,id为作业号,m_size为作业大小 
{
     //请补充使用首次适应算法给作业分配内存的函数代码
    DuLinkList p = m_head;
    while(p != m_last) {
        DuLinkList n = p->next;
        if(!n->data.flag && n->data.size >= m_size) {
            DuLinkList t = new DuNode();
            t->data.ID = id;
            t->data.size = m_size;
            t->data.address = n->data.address;
            t->data.flag = 1;
            n->data.address += m_size;
            n->data.size -= m_size;
            t->prior = p;
            t->next = n;
            p->next = t;
            n->prior = t;
        }
        p = n;
    }
}
void recycle(int id)//回收内存,id为释放内存的作业号 
{
    DuLinkList p = m_head;
    while(p != m_last) {
        DuLinkList n = p->next;
        if(n->data.ID == id) {
            p->next = n->next;
            n->next->prior = p;
            n->next->data.address -= n->data.size;
            m_last->data.size += n->data.size;
            delete n;
            n = n->next;
        }
        if(n != m_last)
            n->next->data.address = n->data.address + n->data.size;
        p = n;
    }
}
int main()
{
 init();
    printf("首次适应算法:\n");
 first_fit(1,15);
 first_fit(2,30);
 recycle(1);
 first_fit(3,8);
 first_fit(4,6);
 recycle(2);
 show();
 DuNode *p = m_head;
 while(p != NULL)
 {
  DuNode *temp =  p;
  p = p->next;
  delete(temp);
  temp = NULL;
 }
 return 0;
}

效果截图:

第2关:最佳适应算法

     假设初始状态下可用的内存空间为55MB,并有如下的请求序列: 作业1申请15MB 作业2申请30MB 作业1释放15MB 作业3分配8MB 作业4分配6MB 作业2释放30MB 请采用最佳适应算法进行内存块的分配和回收,并打印出空闲内存分区链的情况

编程要求

    空闲分区采用带头结点的双向链表来管理,主函数、链表初始化函数和打印函数已实现,只需要补充最佳适应算法分配内存的函数 best_fit以及内存回收的函数recycle()即可。

bool best_fit(int id,int m_size)//使用最佳适应算法给作业分配内存,id为作业号,m_size为作业大小 void recycle(int id)//回收内存,id为释放内存的作业号

代码:

#include <stdio.h>
#include <stdlib.h>
const int Max_length=55;//最大内存
struct areaNode//管理分区的结构体
{
    int ID;//分区号 
    int size;//分区大小 
    int address;//分区地址 
    int flag;//使用状态,0为未占用,1为已占用
};
typedef struct DuNode//双向链表结点
{
  struct areaNode data;//数据域 
  struct DuNode *prior;//指针域 
  struct DuNode *next;
}*DuLinkList;
DuLinkList m_head = new DuNode, m_last = new DuNode;//双向链表首尾指针
void init()//分区链表初始化
{
  m_head->prior = NULL;
  m_head->next = m_last;
  m_last->prior = m_head;
  m_last->next = NULL;
  m_head->data.size = 0;
  m_last->data.address = 0;
  m_last->data.size = Max_length;
  m_last->data.ID = 0;
  m_last->data.flag = 0;
}
void show()
{
  DuNode *p = m_head->next;//指向空闲区队列的首地址 
  printf("+++++++++++++++++++++++++++++++++++++++\n");
  while (p)
  {
    printf("分区号:");
 if (p->data.ID == 0)
   printf("FREE\n");
 else
   printf("%d\n",p->data.ID);
 printf("分区起始地址:%d\n",p->data.address);
 printf("分区大小:%d\n",p->data.size);
 printf("分区状态:");
 if (p->data.flag)
   printf("已被占用\n");
 else
   printf("空闲\n");
 printf("——————————————————\n");
 p = p->next;
  }
}
bool best_fit(int id, int m_size)//最佳适应算法,其中需要查找最佳的存放位置
{
      //请补充使用最佳适应算法给作业分配内存的函数代码
    DuLinkList p = m_head;
    DuLinkList t = nullptr;
    while(p != m_last) {
        DuLinkList n = p->next;
        if(!n->data.flag && n->data.size >= m_size) {
            if(t == nullptr || t->data.size > n->data.size){
                t = n;
            }
        }
        p = n;
    }
    if(t == nullptr)
        return false;
    if(t->data.size == m_size) {
        t->data.flag = 1;
        t->data.ID = id;
    }
    else {
        DuLinkList t2 = new DuNode();
        t2->next = t;
        t2->prior = t->prior;
        t->prior->next = t2;
        t->prior = t2;
        t2->data.ID = id;
        t2->data.flag = 1;
        t2->data.address = t->data.address;
        t->data.address += m_size;
        t2->data.size = m_size;
        t->data.size -= m_size;
    }
    return true;
}
void recycle(int id)//回收内存,id为释放内存的作业号 
{
     //请补充回收作业内存的函数代码
    DuLinkList p = m_head;
    DuLinkList n = nullptr;
    while(p != m_last) {
        n = p->next;
        if(n->data.ID == id) {
            break;
        }
        p = n;
    }
    if(n == nullptr || n == m_last)
        return;
    n->data.flag = 0;
    n->data.ID = 0;
    DuLinkList np = n->prior;
    DuLinkList nn = n->next;
    if(np != m_head && np->data.flag == 0) {
        np->prior->next = n;
        n->prior = np->prior->next;
        n->data.address = np->data.address;
        n->data.size += np->data.size;
        delete np;
    }
    if((nn != nullptr || nn != m_last) && nn->data.flag == 0) {
        nn->next->prior = n;
        n->next = nn->next->prior;
        n->data.size += nn->data.size;
        delete nn;
    }
}
int main()
{
 init();
    //最佳适应算法
 printf("最佳适应算法:\n");
 init();
 best_fit(1,15);
 best_fit(2,30);
 recycle(1);
 best_fit(3,8);
 best_fit(4,6);
 recycle(2);
 show();
 DuNode *p = m_head;
 while(p != NULL)
 {
  DuNode *temp =  p;
  p = p->next;
  delete(temp);
  temp = NULL;
 }
 return 0;
}

效果截图:


总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了动态分区算法(头歌实验)第1关:首次适应算法。第2关:最佳适应算法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/17138.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Yolov5+图像分割+百度AI接口——车牌实时检测识别系统

Hallo&#xff0c;各位小伙伴大家好呀&#xff01;这两天一直在肝项目&#xff0c;都是关于计算机视觉方面的&#xff0c;所以这两天一直也没有更新&#xff08;真的不是我懒&#xff09;&#xff01;在这个过程中我对Yolov5有了更深刻的理解&#xff0c;在原有的Yolov5框架上增…

14.4、SpringWebFlux-2

14.4、SpringWebFlux-2 14.4.3、SpringWebFlux执行流程和核心 API SpringWebFlux 基于 Reactor&#xff0c;默认容器是 Netty&#xff0c;Netty 是高性能的 NIO 框架&#xff0c;异步非阻塞&#xff08;AIO&#xff0c;是 NIO 的升级&#xff09;的框架 14.4.3.1、执行流程 …

jrtplib开源库系列之三:jrtplib发送接收数据流程

说明 前面2篇文章主要说明了如何安装jrtplib库&#xff0c;以及对example1进行了说明&#xff0c;这篇文章主要说下jrtplib库数据的收发流程。 数据收发流程 从例子1就可以很好的说明jrtplib的使用是非常简单的&#xff0c;主要分为以下几步 1. 设置会话参数(比如时间戳&am…

同花顺_代码解析_技术指标_C

本文通过对同花顺中现成代码进行解析&#xff0c;用以了解同花顺相关策略设计的思想 CBJX 成本均线 成本价均线不同于一般移动平均线系统&#xff0c;成本价均线系统首次将成交量引入均线系统&#xff0c;充分提高均线系统的可靠性。成本均线不容易造成虚假信号或骗线&#xf…

牛客网项目-开发注册功能

前言 本文是对牛客网项目的总结&#xff0c;本文主要讲解页面注册逻辑 当我们点击首页的注册按钮时&#xff0c;会跳转到注册页面&#xff0c;然后再祖册页面提交账号&#xff0c;密码邮箱后会跳转到首页或者直接登录页面进行登录&#xff0c;这个操作可以自己设定 【设计逻辑…

SAP ABAP BAPI_SALESORDER_CREATEFROMDAT2 成本中心 kostl

BAPI_SALESORDER_CREATEFROMDAT2提供参数无成本中心字段&#xff0c;所以需要用扩展字段实现。 BAPE_VBAK&#xff1a; BAPE_VBAKX VBAKKOZ VBAKKOZX 封装扩展结构&#xff1a; DATA: LS_EXTENSION TYPE BAPIPAREX, LT_EXTENSION TYPE TABLE OF BAPIPAREX. DATA: LS_B…

目标检测论文解读复现之十一:基于特征融合与注意力的遥感图像小目标检测

前言 此前出了目标改进算法专栏&#xff0c;但是对于应用于什么场景&#xff0c;需要什么改进方法对应与自己的应用场景有效果&#xff0c;并且多少改进点能发什么水平的文章&#xff0c;为解决大家的困惑&#xff0c;此系列文章旨在给大家解读最新目标检测算法论文&#xff0c…

【MySQL】5.触发器

文章目录1. 触发器概述2. 触发器的相关语法3. 触发的NEW与OLD4. 总结1. 触发器概述 触发器&#xff0c;就是一种特殊的存储过程。触发器和存储过程一样是一个能够完成特定功能、存储在数据库服务器上的SQL片段&#xff0c;但是触发器无需调用&#xff0c;当对数据库表中的数据…

python批量读取nc气象数据并转为tif

python批量nc数据转tif 各类地理数据中&#xff0c;NC格式是很常见的&#xff0c;然而这种格式ArcGIS是无法打开的。一旦下载的话nc也是多时序的&#xff08;多年、多月等等&#xff09;&#xff0c;让我们看看如何批量操作吧。 直接上代码&#xff1a; import numpy as np …

[附源码]Python计算机毕业设计本科生外出请假管理信息系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

数据结构和算法

1.数据结构 食谱和算法之间最大的区别就在于算法是严密的。食谱上经常会有描述得比较模糊的部分&#xff0c; 而算法的步骤都是用数学方式来描述的&#xff0c;所以十分明确。 算法和程序有些相似&#xff0c;区别在于程序是以计算机能够理解的编程语言编写而成的&#xff0c;…

构造函数详解

构造函数详解1.构造函数的概念与特性2.默认构造函数&#xff08;1&#xff09;概念&#xff08;2&#xff09;分类&#xff08;3&#xff09;工作原理3.初始化列表&#xff08;1&#xff09;定义&#xff08;2&#xff09;为什么使用初始化列表&#xff08;3&#xff09;必须使…

WebRTC系列<五>我与一位大佬的聊天记录

原本打算想用webrtc部署虚幻项目。后来在了解虚幻过程中&#xff0c;得知虚幻有像素流插件&#xff0c;导出项目里带有STUN和TURN服务&#xff0c;但是在webGL项目里比如three.js、babylon.js如果也能部署在服务器端&#xff0c;那就厉害了&#xff0c;也很有想象力空间。 基本…

表白墙网站练习【前端+后端+数据库】

表白墙网站练习【前端后端数据库】 开发该表白墙&#xff08;简单网站&#xff09;的基本步骤&#xff1a; 1.约定前后端交互接口 2.开发服务器代码 编写Servlet能够处理前端发来的请求编写数据库代码&#xff0c;来获取/存储关键数据 3.开发客户端代码 基于ajax能够构造请…

一体化Ethercat通信伺服电机在汇川H5U PLC上的应用案例介绍(上)

内容介绍了一体化低压伺服Ethercat通信的电机在汇川H5UPLC上的使用&#xff0c;本篇主要讲解环境的搭建以及使用AutoShop软件的在线调试功能&#xff0c;简单控制电机位置、速度模式运行&#xff1b; 一、系统构成 本系统主要构成是电脑&#xff0c;H5U-1614MTD-A8&#xff0c;…

家长杂志家长杂志社家长编辑部2022年第30期目录

卷首语 读懂童心,营造乐学趣学好场景 本刊编辑部; 1 本刊视线_关注《家长》投稿&#xff1a;cn7kantougao163.com 留守儿童学习动力不足的成因与激发策略 蔡斌林; 4-6 农村留守儿童加强心理健康教育的策略 张芸; 7-9 本刊视线_学校体育 中学体育线上线下教学融…

【Struts2框架】idea快速搭建struts2框架

文章目录什么是SSH框架&#xff1f;Struts2框架1、struts2的环境搭建1.1 创建web项目&#xff08;maven&#xff09;&#xff0c;导入struts2核心jar包1.2 配置web.xml&#xff08;过滤器&#xff09;&#xff0c;是struts2的入口&#xff0c;先进入1.3 创建核心配置文件struts…

STM32 Bootloader开发记录 3 固件签名校验

STM32 Bootloader开发记录 3 固件签名校验 文章目录STM32 Bootloader开发记录 3 固件签名校验1. 移植mbedtls1.1 编译mbedtls1.2 修复rsa_sign的一个bug1.3 测试RSA1.3.1 **RSA加解密&#xff1a;**1.3.2 **RSA签名验签&#xff1a;**1.3.3 **生成秘钥对**1.4 移植到STM321.4.1…

NFV中:DPDK与SR-IOV应用场景及性能对比

DPDK与SR-IOV两者目前主要用于提高IDC&#xff08;数据中心&#xff09;中的网络数据包的加速。但是在NFV&#xff08;网络功能虚拟化&#xff09;场景下DPDK与SR-IOV各自的使用场景是怎样的&#xff1f;以及各自的优缺点&#xff1f; 本文主要通过从以下几点来阐述这个问题&a…

视觉SLAM十四讲(高翔版本),ch4章节部分笔记

目标&#xff1a;理解slam的框架以及它的理论知识。供以后自己查阅。 这一章主要非常重要&#xff0c;也是理解后续优化的基础&#xff0c;它是将旋转矩阵和平移向量&#xff0c;转化为李代数的形式进行优化&#xff0c;因为它有很多好处。好处如下&#xff1a; 意思就是采用…