首页 > 其他分享 >8.3 边界标识法

8.3 边界标识法

时间:2024-06-20 14:10:06浏览次数:7  
标签:8.3 WORD 边界 pav 标识 tag llink rlink size

8.3 边界标识法

参考书:《数据结构(C语言版)》严蔚敏

#include <cstdio>

const unsigned miniSize = 1000;

// head, foot, *Space
struct WORD {
    union {
        WORD    *llink;  // 头部域, 指向前驱节点
        WORD    *uplink; // 底部域, 指向本节点头部
    };
    unsigned    tag:1;   // 标志块,0:空闲,1:占用,头部和尾部均有
    unsigned    size:31; // 头部域,块大小
    WORD        *rlink;  // 头部域, 指向后继节点
};

inline WORD* FootLoc(WORD* p) {
    return p + p->size - 1;
}

// 首次拟合法
WORD* AllocBoundTag(WORD* pav, unsigned n) {
    WORD* p = pav;
    // 找到第一个可用节点
    while (p && p->size < n && p->rlink != pav)
        p = p->rlink;

    if (!p || p->size < n)
        return nullptr;

    WORD* f = FootLoc(p); // 指向底部
    pav = p->rlink;       // pav 指向 *p 节点的后继节点
    if (p->size - n <= miniSize) { // 整块分配,不保留 <= miniSize 的剩余内存
        if (pav == p) {   // p 的后继节点是它自己,整个空间表就剩这一块空余内存,分配完后空间表变为空表
            pav = nullptr;
        } else {
            pav->llink = p->llink; // 在链表中删除 p 节点
            p->llink->rlink = pav;
        }
        p->tag = f->tag = 1; // 修改分配节点头部和底部标志
    } else { // 分配该块的后 n 个字
        f->tag = 1; // 修改分配块的底部标志
        p->size -= n;
        f = FootLoc(p); // f 指向未分配块底部
        f->tag = 0;
        f->uplink = p;
        p = f + 1; // p 指向分配块头部
        p->tag = 1; // 修改分配块的头部标志
        p->size = n;
    }
    return p;
}

void Free(WORD* pav, WORD* p) {
    bool pre = (p - 1)->tag;
    bool next = (p + p->size)->tag;
    if (pre && next) {
        p->tag = 0;
        FootLoc(p)->uplink = p;
        FootLoc(p)->tag = 0;
        if (!pav) {
            pav = p->llink = p->rlink = p;
        } else {
            WORD* q = pav->llink; // p 节点插入到 pav 节点前面
            p->rlink = pav;
            p->llink = q;
            q->rlink = p;
            pav->llink = p;
            pav = p; // 令刚分配的节点为下次查询时最先查询的节点
        }
    } else if (!pre && next) {
        unsigned n = p->size;
        WORD* s = (p - 1)->uplink; // 左空闲块头部地址
        s->size += n;
        WORD* f = p + n - 1;
        f->uplink = s;
        f->tag = 0;
    } else if (pre && !next) {
        WORD* t = p + p->size; // 右空闲块头部地址
        p->tag = 0;
        WORD* q = t->llink;
        p->llink = q;
        q->rlink = p;
        WORD* q1 = t->rlink;
        p->rlink = q1;
        q1->llink = p;
        p->size += t->size;
        FootLoc(t)->uplink = p;
    } else {
        unsigned n = p->size;
        WORD* s = (p - 1)->uplink; // 左空闲块头部地址
        WORD* t = p + p->size; // 右空闲块头部地址
        s->size += n + t->size;
        WORD* q = t->llink;
        WORD* q1 = t->rlink;
        q->rlink = q1;
        q1->llink = q;
        FootLoc(t)->uplink = s;
    }
}

int main() {
    printf("8.3\n");
    return 0;
}

标签:8.3,WORD,边界,pav,标识,tag,llink,rlink,size
From: https://www.cnblogs.com/AngleLin/p/18258554

相关文章

  • C语言 - 标识符
    C语言中的标识符有助于识别C代码中的变量、常量、函数等。C是一种高级计算机语言,它允许您使用名称引用内存位置,而不是以二进制或十六进制形式使用其地址。C标识符标识符是用户定义的名称,以便于引用内存。它还用于定义程序中的各种元素,例如函数、用户定义类型、标签等。......
  • 微软Windows 10系统安全标识符(SID)与Sysprep使用指南
    一、了解SID在Windows操作系统中,安全标识符(SID)是用于唯一标识安全主体(如用户账户、计算机账户等)的字符串。对于域环境中的计算机和用户,SID的生成具有特定的规则。在域中,对象的SID由域范围的SID和具有唯一性的相对标识符(RID)组成,其中RID由域中的RIDMaster分配。工作组计算机和用户......
  • 关于EOF标识符
    EOF的概念EOF是C语言中表示文件结束的标志符号,通常被定义为-1,它用于指示已到达文件的末尾或输入流的末尾。EOF的使用在输入操作中,EOF常常用于判断是否到达了文件末尾或输入流末尾,以便终止读取操作。例如,在使用scanf函数进行输入时,可以通过将scanf函数的返回值与EOF进行比较......
  • Fluent边界|03 速度入口边界
    速度入口边界是Fluent中计算不可压缩流动时最常用的入口边界。速度入口边界条件用于定义在入口边界处的流速及相关标量特性。采用此类边界条件时,入口总压需要通过计算来确定(通过调整入口总压使得入口速度满足输入值)。速度入口边界条件可用于不可压缩流动和可压缩流动。注......
  • MySQL 8.3.0 主从热备
    IP角色版本192.168.140.153主8.3.0192.168.140.159从8.3.0一、准备环境1、卸载mariadbrpm-qa|grepmariadbrpm-emariadb-libs--nodeps2、安装依赖yum-yinstallperl二、安装MySQL1、下载安装包wgethttps://downloads.mysql.com/archives/get/p/23/file/mysq......
  • vue3 高德安徽省边界 密钥必须添加否则会出现无法使用DistrictSearch的方法也不报错
    <template> <divclass="centermap"ref="mapContainer"></div></template><scriptsetuplang="ts">import{ref,onMounted}from'vue';importAMapLoaderfrom'@amap/amap-jsapi-l......
  • 第四章: 全面梳理Java 标识符变量的声明,基本数据类型,String类型以及相互之间的类型
    1.关键字和保留字关键字(keyword)是指被Java语言赋予了特殊含义,用做专门用途的字符串(单词)其特点就是关键字中所有字母都为小写官方地址:https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html保留字(reservedword)是当前Java版本尚未使用,但以......
  • ARM64中的ASID地址空间标识符
    1.从ARM32到ARM64从ARM32到ARM64不止将处理器从32位升级到了64位,还有许多性能的技术也得到了极大的提升,光是个头长了可不行啊!能耐也得跟着长啊!哈哈哈1.1ARM32的TLB机制如上图所示,上一讲我们讲了TLB的每一条表项都有一个bit用来表示自己是全局的(内核空间)还是本地的(用户空间)。......
  • 华为OD刷题C卷 - 每日刷题 13(图像物体的边界,英文输入法)
    1、(图像物体的边界):这段代码是解决“图像物体的边界”的问题。它提供了一个Java类Main,其中包含main方法和getResult方法,以及一个内部UnionFindSet类,用于计算像素1代表的物体的边界个数。main方法首先读取二维数组的行数m和列数n,然后读取二维数组matrix中的像素值。接着,调用......
  • 标识符
    标识符(identifier)指的是用来识别各种值的合法名称。最常见的标识符就是变量名,以及后面要提到的函数名。JavaScript语言的标识符对大小写敏感,所以a和A是两个不同的标识符。标识符有一套命名规则,不符合规则的就是非法标识符。JavaScript引擎遇到非法标识符,就会报错。中文是合......