数据结构(C语言实现)-线性表(3)(数组描述的线性链表)

用数组描述的线性链表又叫静态链表。

静态链表中,元素存放在结构体数组里,每一个数组元素代表静态链表的一个“结点”,同时结构体中除了元素还有一个游标cur,指示下一个“结点”对应的的数组下标
静态链表用结构体中的游标(cursor)代替了指针。这种存储结构像顺序表一样需要预分配一段较大的空间,但在插入删除元素时不需要移动元素,只需要修改游标,所以具有链表的优点。

静态链表内部分为数据链表和备用空闲链表两部分:

1.备用空闲链表:数组0号元素(后文中用a[0]表示)代表备用空闲头结点,该结点的数据域不存储元素,游标指向第一个空闲结点的下标。最后一个空闲结点的下标指向a[0]。当a[0].cur=0(即指向自己)时,表示备用链表已经用光了。
2.数据链表:数组最后一个元素(后文用a[max_size-1]表示)代表数据链表的头结点,该结点默认不存储数据,其游标指向数据链表第一个结点的下标。数据链表尾最后一个结点的游标指向a[0]表示已到链表尾。

静态链表的插入与删除操作与单链表类似,但是由于不需要动态申请内存空间,故需要手动实现malloc和free这两个函数。

下列代码中的头文件在这里,不看也不影响理解

#include"head.h"

#define MAXSIZE 100  // 定义数组大小

typedef char Elemtype;

typedef struct {
	Elemtype data;
	int cur;
}component,SLinkList[MAXSIZE];


//链表初始化
int Init_SL(SLinkList &S)
{
	for (int i = 0; i < MAXSIZE - 2; i++) // 最后一个结点不存储元素,循环到倒数第二个结点
	{
		S[i].data = NULL;//创建空链表
		S[i].cur = i + 1;//把空结点连成备用链表
	}
	S[MAXSIZE - 2].cur = 0;//最后一个存元素的空结点指向头结点

	S[MAXSIZE - 1].cur = 0;//最后一个结点指向零表示数据链表没有元素
	return OK;
}


// 在链表中查找第一个值为e的元素,返回它的下标,没有则返回0
int LocateElem_SL(SLinkList S, Elemtype e)
{
	int i=S[MAXSIZE-1].cur;
	while (i && S[i].data != e)
		i = S[i].cur;
	return i;
}


//若备用链表有空结点,返回第一个空节点下标,否则返回0
int malloc_SL(SLinkList &S)
{
	int i = S[0].cur;  // 备用链表第一个结点的下标给i
	if (S[0].cur) S[0].cur = S[i].cur;//将分配掉的结点从备用链表去掉
	return i;
}


//将下标为k的结点收回到备用链表
void free_SL(SLinkList &S, int k)
{
	S[k].cur = S[0].cur;
	S[0].cur = k;
}


//向链表第i个节点前插入元素e
int Insert_SL(SLinkList &S, int i, Elemtype e)
{
	int j = MAXSIZE - 1 , p;//j代表第k个结点的下标
	for (int k = 0; k < i - 1; k++)
		j = S[j].cur;

	p = malloc_SL(S);
	S[p].data = e;
	S[p].cur = S[j].cur;
	S[j].cur = p;

	return OK;
}


//删除链表中第i个元素
int Delete_SL(SLinkList *S, int i)
{
	int j = MAXSIZE - 1 , p;//p是没有感情的工具人
	for (int k = 0; k < i - 1; k++)
	{
		j = S[j]->cur;
	}

	p = S[j]->cur;
	j = S[p]->cur;
	free_SL(*S,p);

	return OK;
}

你可能感兴趣的:(数据结构)