10.3-4
实现ALLOCATE和FREE,使双向链表在多数组表示法中在存储器保持紧凑,占前n个位置。
自由表Free初始化:0,1,2,...
其实是一个stack。0是栈顶元素,Free是栈顶指针。下一个被分配之对象是最后被释放的。
自由表只使用next数组。Free和双链表L交错。
实现ALLOCATE和FREE,使双向链表在多数组表示法中在存储器保持紧凑,占前n个位置。
自由表Free初始化:0,1,2,...
其实是一个stack。0是栈顶元素,Free是栈顶指针。下一个被分配之对象是最后被释放的。
自由表只使用next数组。Free和双链表L交错。
地址是数组下标,int类型。
看了这篇blog,我就有灵感了。
#include<stdio.h>
#define NIL -1
#define MAX 11
int Free;//自由表表头
int L;//双链表表头
int m;//L的元素个数。L新增结点时,m++。
typedef char ElemType;
int next[MAX];//后继
ElemType key[MAX];//值
int prev[MAX];//前驱
void error(const char*const s)
{
puts(s);exit(1);
}
void initial()
{
L=NIL;Free=0;m=0;
int i;
//整个数组都属于自由表,含MAX个未分配对象
for(i=1;i<MAX;i++) next[i-1]=i;
next[MAX-1]=NIL;
}
int ALLOCATE()
{//分配Free表头对象(栈顶)
if(Free==NIL) error("Out of space.");
else{
int space=Free;Free=next[Free];m++;
return space;
}
}
void FREE(int p)
{/*在释放前,双链表L紧凑占据数组前m个位置。
释放后,L应紧凑占据前m-1个位置。
若p是第0~2个,则要将第m-1个位置的元素挪到p的位置;
若p是第m-1个,就不需挪。然后修改prev,next指针,和Free。
Free表头变成了新增的m。*/
if(p<0||p>m-1) error("Wrong index.");
/*将数组中第m-1个位置元素挪到第p位。L中各元素的逻辑顺序不变。
只是物理地址为m-1的元素,物理地址变为p。*/
if(p!=m-1){//printf("%d\n",p);//system("pause");
key[p]=key[m-1];next[p]=next[m-1];prev[p]=prev[m-1];
if(prev[p]!=NIL) next[prev[p]]=p;
else L=p;
if(next[p]!=NIL) prev[next[p]]=p;
}
next[m-1]=Free;Free=m-1;m--;
}
void insert(ElemType elem)
{//在L中插入元素
int space=ALLOCATE();
key[space]=elem;next[space]=L;prev[space]=NIL;
if(L!=NIL) prev[L]=space;
L=space;
}
int search(ElemType elem)
{
int i;
for(i=L;i!=NIL;i=next[i]) if(key[i]==elem) return i;
return NIL;
}
void delete(ElemType elem)
{//删除第一个给定值的结点
int index=search(elem);
if(index!=NIL){
if(prev[index]!=NIL) next[prev[index]]=next[index];
else L=next[index];
if(next[index]!=NIL) prev[next[index]]=prev[index];
FREE(index);
}
}
void traverse()
{
int i;
for(i=0;i<MAX;i++) printf("%3d",prev[i]);putchar('\n');
for(i=0;i<MAX;i++) printf(" %c",key[i]);putchar('\n');
for(i=0;i<MAX;i++) printf("%3d",next[i]);putchar('\n');
printf("L:%3d m:%3d Free:%3d",L,m,Free);//system("pause");
putchar('\n');
for(i=L;i!=NIL;i=next[i]) putchar(key[i]);putchar('\n');
if(L!=NIL){
for(i=L;next[i]!=NIL;i=next[i]);
for(;i!=NIL;i=prev[i]) putchar(key[i]);putchar('\n');
}
for(i=Free;i!=NIL;i=next[i]) printf("%3d",i);putchar('\n');putchar('\n');
}
int main(void)
{
int free;//自由表表头
int L;//双链表表头
initial();
insert('a');insert('b');insert('c');insert('d');
insert('e');insert('f');insert('g');
traverse();
delete('g');delete('c');
delete('a');traverse();
insert('y');insert('z');traverse();
delete('z');insert('x');traverse();
insert('b');insert('b');insert('b');insert('b');
traverse();delete('y');traverse();
insert('a');insert('a');traverse();insert('a');
return 0;
}