一、解析

我们把这种用数组描述的链表叫做静态链表,又称游标实现法。

实现方法:

首先让数组的元素都是有两个数据域组成,datacur。也就是说,数组的每个下标都对应一个data和一个cur。数据域data,用来存放数据元素,也就是通常我们要处理的数;而游标cur相当于单链表中的next指针,存放该元素的后继在数组中的下标。

 

对于数组的第一个和最后一个元素作为特殊元素处理,不存数据。通常把未使用的数组元素称为备用链表。而数组第一个元素,即下标为0的元素的cur就存放备用链表的第一个结点的下标;而数组的最后一个元素的cur则存放第一个有数值的元素的下标,相当于链表中的头结点作用,当整个链表为空时,则为02

静态链表_数据结构

注意:

1. 对于不提供结构struct的程序设计语言,可以使用一对并行数组datacur来处理。

2. 有些书中把数组的第二个元素用来作为头结点,实现原理相同,只不过是取得存放位置不同。

 

静态链表c程序实现

用数组来代替指针,描述单链表,叫做静态链表。其中数组的元素都是由两个数据域组成,datacurdata用来存放数据,cur相当于单链表中的next指针,存放该元素的后继在数组中的下标,我们把cur称为游标,因此,静态链表又叫游标实现法。

我们把静态链表中未被使用的数组元素称为备用链表。我们对数组的第一个和最后一个元素做特殊处理,不存数据。其中,数组的第一个元素,即下标为0的元素的cur用来存放备用链表的第一个结点的下标;而数组的最后一个元素的cur则存放第一个有数值的元素的下标,相当于单链表中的头结点。

下面给出一个例子,假设我们的静态链表存放了“甲”,“乙”,“丙”,“丁”四个数据,静态链表的长度为1000,则该静态链表如下表所示。下表中红色的“5”表示如果再往静态链表中存放一个数据,将存放在下标为5的位置。红色的“0”表示下一个位置数据位空,即“丁”是目前静态链表中最后一个元素。红色的“1”表示静态链表中下标为1处的“甲”是本静态链表的第一个元素。

Data

 

 

 

 

 

Cur

5

2

3

4

0

 

 

 

1

下标

0

1

2

3

4

5

6

。。。

999

#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 1000
typedef  int ElemType;
typedef struct
{
	ElemType data;
	int cur;
}StaticLinkList[MAXSIZE];

typedef enum
{
	ERROR=-1,
	OK=1,
}Status;

/*将下标为k的空闲结点回收到备用链表*/
void Free_SSL(StaticLinkList space,int k)
{
	space[k].cur=space[0].cur;
	space[0].cur=k;
}

/*返回L中数据元素个数*/
int ListLength(StaticLinkList L)
{
	int j=0;
	int i=L[MAXSIZE-1].cur;
	while(i)
	{
		i=L[i].cur;
		j++;
	}
	return j;
}

/*将一维数组space中各分量链成一个备用链表*/
Status InitList(StaticLinkList space)
{
	int i;
	for(i=0;i<MAXSIZE - 1;i++)
	{
		space[i].cur=i+1;
	}
	space[MAXSIZE-1].cur=0;
	return OK;
}

/*若备用链表非空,则返回分配的结点下标,否则返回0*/
int Malloc_SLL(StaticLinkList space)
{
	int i=space[0].cur;
	if(space[0].cur)
	{
		space[0].cur=space[i].cur;
	}
	return i;
}

/*在L中第i个元素前插入新的数据元素e*/
Status ListInsert(StaticLinkList L,int i,ElemType e)
{
	int j,k,l;
	k=MAXSIZE-1;
	if((i<1)||(i>ListLength(L)+1))
	{
		return ERROR;
	}
	j=Malloc_SLL(L);
	if(j)
	{
		L[j].data=e;
		for(l=1;l<=i-1;l++)
		{
			k=L[k].cur;
		}
		L[j].cur=L[k].cur;
		L[k].cur=j;
		return OK;
	}
	return ERROR;
}

/*删除L中第i个数据元素*/
Status ListDelete(StaticLinkList L,int i)
{
	int j,k;
	if((i<1)||(i>ListLength(L)))
	{
		return ERROR;
	}
	k=MAXSIZE-1;
	for(j=1;j<=i-1;j++)
	{
		k=L[k].cur;
	}
	j=L[k].cur;
	L[k].cur=L[j].cur;
	Free_SSL(L,j);
	return OK;
}

/*打印L中各元素*/
void ListDisp(StaticLinkList L)
{
	int i=L[MAXSIZE-1].cur;

	while(i!=0)
	{
		printf("%d ",L[i].data);
		i=L[i].cur;
	}
	printf("\n");
}

int main(void)
{
	StaticLinkList test;
	InitList(test);
	printf("after InitList,StaticLinkList test is:");
	ListDisp(test);
	int i;
	for(i=0;i<10;i++)
	{
		ListInsert(test,i,i*10);
		printf("after ListInsert,StaticLinkList test is:");
		ListDisp(test);
	}

	for(i=0;i<10;i++)
	{
		ListDelete(test,1);
	    printf("after ListDelete,StaticLinkList test is:");
	    ListDisp(test);
	}
	return EXIT_SUCCESS;
}