//可利用空间表的结点结构定义
typedef struct WORD{ //WORD:内存字类型
union{ //head和foot分别是结点的第一个字和最后的字
WORD *llink; //头部域,指向前驱结点
WORD *uplink; //底部域,指向本结点头部
};
int tag; //快标志,0:空闲,1:占用,头部和尾部均有
int size; //头部域,块大小
WORD *rlink; //头部域,指向后继结点
OtherType other; //字的其他部分
}WORD,head,foot,*Space; //*Space:可利用空间指针类型
//算法8.1
Space AllocBoundTag(Space &pav,int n){
//若有不小于n的空闲块,则分配相应的存储块,并返回其首地址;否则返回NULL
//若分配后可利用空间表不空,则pav指向表中刚分配过的结点的后继结点
for(p=pav;p&&p->size<n&&p->rlink!=pav;p=p->rlink); //找不到小于n的空闲块
if(!p||p->size<n)
return NULL;
else{ //p指向找到的空闲块
f=FootLoc(p); //指向底部
pav=p->rlink;
if(p->size-n<=e){
if(pav==p)
pav=NULL;
else{ //在表中删除分配的结点
pav->llink=p->llink;
p->llink->rlink=pav;
}
p->tag=f->tag=1; //修改分配结点的头部和底部标志
}
else{ //分配该块的后n个字
f->tag=1; //修改分配块的底部标志
p->size-=n; //设置剩余块大小
f=FootLoc(p); //指向剩余块底部
f->tag=0; //设置剩余块底部
f->uplink=p; //
p=f+1; //指向分配块头部
p->tag=1; //设置分配块头部
p->size=n;
}
return p; //返回分配块首地址
}
}
//---------------------伙伴系统可用空间表的结构-------------------------
#define m 16
typedef struct WORD_b{
WORD_b *llink; //指向前驱结点
int tag; //块标志,0:空闲,1:占用
int kvak; //块大小,值为2的幂次k
WORD_b *rlink; //头部域,指向后继结点
OtherType other; //字的其他部分
}WORD_b,head; //WORD:内存字类型,结点的第一个字也称为head
typedef struct HeadNode{
int nodesize; //该链表的空闲块的大小
WORD_b *first; //该链表的表头指针
}FreeList[m+1]; //表头向量类型
//算法8.2
WORD_b *AllocBuddy(FreeList &avail,int n){
//avail[0..m]为可利用空间表,n为申请分配量,若有不小于n的空闲块,
//则分配相应的存储块,并返回其首地址;否则返回NULL
for(k=0;k<=m&&(avail[k].nodesize<n+1||!avail[k].first);k++);
if(k>m)
return NULL;
else{
pa=avail[k].first;
pre=pa->llink;
suc=pa->rlink;
if(pa==suc)
avail[k].first=NULL;
else{
pre->rlink=suc;
suc->llink=pre;
avail[k].first=suc;
}
for(i=1;avail[k-i].nodesize>=n+1;i++){
pi=pa+2^(k-i);
pi->rlink=pi;
pi->llink=pi;
pi->tag=0;
pi->kval=k-1;
avail[k-i].first=pi;
}
pa->tag=1;
pa->kval=k-(--i);
}
return pa;
}
//算法8.3
void MarkList(GList GL){
//遍历非空广义表GL(GL!=NULL且GL->mark==0),对表中所有未加标志的结点加标志
t=NULL;
p=GL;
finished=FALSE;
while(!finished){
while(p->mark==0){
p->mark=1;
//MarkHead(p)的细化
q=p->p.hp;
if(q&&q->mark==0){
if(q->tag==0)
q->mark=1;
else{
p->p.hp=t;
p->tag=0;
t=p;
p=q;
}
}
}
q=p->p.tp;
if(q&&q->mark==0){
p->p.tp=t;
t=p;
p=q;
}
else{
while(t&&t->tag==1){
q=t;t=q->p.tp;
q->p.tp=p;
p=q;
}
if(!t)
finished=TRUE;
else{
q=t;
t=q->p.hp;
q->p.hp=p;
p=q;
p->tag=1;
}
}
}
}