您的位置:首页 > 其它

静态链表的原理及实现

2017-03-18 10:04 387 查看
静态链表是一种使用数组模拟链表的方法,在某些不支持指针的语言中,可以用它来模拟链表。

静态链表使用一个数组,但是该数组通过下标指向连成两个“链表”,一个用来存储尚未存放数据的节点,另一个存储已经存放数据的节点。

静态链表的数据结构如下:

#define MAXSIZE 1000
typedef struct
{
int data;
int cur;
}List,Linklist[MAXSIZE];


结构体数组Linklist中data为数据(假定为int型),cur为下一个元素的下标(类似于链表中的指向下一个节点的指针)。MAXSIZE为最大可以存储的数据元素个数。

静态链表的逻辑形式如下:



该图为一个静态链表的初始状态。

初始状态下每一个节点的cur为下一个节点的下标。最后一个节点暂时存放0号节点的下标。

实现:

void init(Linklist s)
{
int i;
for(i=0;i<MAXSIZE-1;i++)
s[i].cur=i+1;
s[i].cur=0;
}




上图为静态链表使用的某个状态。

前面说过静态链表实际上维持两个链表。存放元素的链表首节点由MAXSIZE-1获得(s[MAXSIZE-1].cur),最后一个节点因为指向0号节点,也可获得。而空链表首节点为0号节点,通过首节点即可找到下一个可用的空节点

插入节点时,从0号节点开始查找可用的节点,若存在可用节点,则加入,并修改一些节点的指向。

为了方便起见,将插入分为两个部分:插入首节点,插入其他节点。

插入首节点:

//插入第一个节点时,需要将s[MAXSIZE-1]指向首节点
void insertFirst(Linklist s,int data)
{
s[MAXSIZE-1].cur=1;
s[1].data=data;
s[1].cur=0;
s[0].cur=2;
return ;
}
插入其他节点:

int insert(Linklist s,int pos,int data)//链表,插入位置,数据
{
if(pos>getLength(s)+1||pos<=0)
{
printf("wrong insert position!\n");
return -1;
}
int i,j,n;
i=getSpacePos(s);
s[i].data=data;
n=MAXSIZE-1;
for(j=1;j<pos;j++)
n=s
.cur;
s[i].cur=s
.cur;
s
.cur=i;
return 0;
}


其中,getLength(s)获取存放数据链表的长度,getSpacePos(s)获取下一个可用的节点位置。

int getLength(Linklist s)
{
int count,n;
count=0;
n=MAXSIZE-1;
while(s
.cur!=0)
{
count++;
n=s
.cur;
}
return count;
}
int getSpacePos(Linklist s)
{
int i=s[0].cur;//s[0]指向下一个可用的节点位置
if(i)
{
s[0].cur=s[i].cur;//使得s[0]继续指向下一个可用的节点位置
}
return i;
}
删除节点同理:找到节点位置,删除,修改指向。

int deletePos(Linklist s,int pos)
{
if(pos>getLength(s)+1||pos<=0)
{
printf("wrong delete position!\n");
return -1;
}
int n=MAXSIZE-1;
while(s
.cur!=0)
{
if(s
.cur==pos)
{
if(s[s
.cur].cur==0)
s
.cur=0;
else
s
.cur=s[s
.cur].cur;
release(s,pos);
break;
}
n=s
.cur;
}
return 0;
}
其中realease(s,pos)用来维护空链表,修改空链表指向。

//释放节点,将该节点放在0号节点后面
void release(Linklist s,int pos)
{
s[pos].cur=s[0].cur;
s[0].cur=pos;
}
遍历存放数据的链表:

void print(Linklist s)
{
printf("pos\tdata\tnext\n");
int i=s[MAXSIZE-1].cur;
while(s[i].cur!=0)
{
printf("%d\t%d\t%d\n",i,s[i].data,s[i].cur);
i=s[i].cur;
}
printf("%d\t%d\t%d\n",i,s[i].data,s[i].cur);
return ;
}
完整的demo下载:静态链表
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: