C语言实现静态链表
静态链表产生的原因:因为某些计算机语言中没有指针,所以利用数组结构来模拟链式结构。
静态链表的实现,静态链表是对传统链表的仿造,实际上是用数组结构实现的,具体而言是结构体数组,数组的每个元素是一个结构体,该结构体定义如下:
typedef struct
{
int data;
int cur;
} component, SLL[MAXSIZE];
结构体中的两个字段第一个为data数据域,第二个字段为cur下标域,这个下标域相当于传统链表中的next指针域,传统链表的next指针域指向下一个结点结构体,而cur下标域指向下一个结构体数组元素。
关于静态链表有两点需要说明:首先是上面提到的结构体数组元素cur域在逻辑上指向下一个结构体数组元素,但不一定是绝对连续的,cur域可能指向结构体数组空间中的任意一个结构体元素,并且最后一个结构体元素中的cur域值为0,这表示它是尾结点,没有任何后继指向。其次需要注意的是在我们实现传统链表的时候,我们会实现创建、插入和删除等的基本操作,其中会用到malloc()和free()函数,所以在实现静态链表的时候,因为是仿造传统链表,所以我们也需要仿造malloc()和free()函数,假设其名称是malloc_S()和free_S(),这两个函数是对静态链表的结构体元素的分配和释放,就相当于仿造了malloc()和free()函数对传统链表的结构体结点的内存分配和释放。
下面是malloc_S()和free_S()函数的具体实现,如下:
int malloc_S(SLL space)
{
int i;
i = space[0].cur;
if(space[0].cur)
{
space[0].cur = space[i].cur;
}
return i;
}
void free_S(SLL space, int k)
{
space[k].cur = space[0].cur;
space[0].cur = k;
return;
}
这两个函数很重要,其中还要说明的是这两个函数都传入的参数space,它是SLL类型的,即结构体数组类型,这是我们一开始在定义结构体后定义的,space即为备用空间,可以把它理解为一个库,在我们需要分配结构体元素时,调用malloc_S()函数进行结构体元素的分配,在我们需要释放不需要的结构体元素时,调用free_S()函数进行结构体元素的释放,其实静态链表中结构体元素的释放就是将该结构体元素归还给备用空间space。这个SLL类型的space参数几乎每个静态链表的基本操作函数都要使用。而在实现传统链表时,则没有类似SLL类型的参数,因为我们使用的是系统的malloc()和free()函数。
静态链表的定义及其基本操作代码如下:
StaticLinkedList.h
# include <stdio.h>
# define MAXSIZE 100
typedef struct
{
int data;
int cur;
} component, SLL[MAXSIZE];
void init_list(SLL);
int malloc_S(SLL);
void free_S(SLL, int);
int create_list(SLL);
void traverse_list(SLL, int);
bool insert_list(SLL, int, int, int);
bool delete_list(SLL, int, int, int *);
int locate_list(SLL, int, int);
StaticLinkedList.c
# include "StaticLinkedList.h"
int malloc_S(SLL space)
{
int i;
i = space[0].cur;
if(space[0].cur)
{
space[0].cur = space[i].cur;
}
return i;
}
void free_S(SLL space, int k)
{
space[k].cur = space[0].cur;
space[0].cur = k;
return;
}
void init_list(SLL space)
{
int i;
for(i=0; i<MAXSIZE-1; ++i)
{
space[i].cur = i+1;
}
space[MAXSIZE-1].cur = 0;
}
int create_list(SLL space)
{
int len;
int i;
int n;
int S = malloc_S(space);
int q = S;
printf("请输入您要生成的结点的个数:");
scanf("%d", &len);
for(i=1; i<=len; ++i)
{
n = malloc_S(space);
scanf("%d", &space[n].data);
space[q].cur = n;
q = n;
}
space[q].cur = 0;
return S;
}
void traverse_list(SLL space, int S)
{
int p = space[S].cur;
printf("\n");
while(0 != p)
{
printf("%d ", space[p].data);
p = space[p].cur;
}
printf("\n");
return;
}
bool insert_list(SLL space, int S, int pos, int val)
{
int i = 0;
int p = S;
while(0!=p && i<pos-1)
{
p = space[p].cur;
i++;
}
if(i>pos-1 || 0==p)
{
return false;
}
int n = malloc_S(space);
if(n)
{
space[n].data = val;
space[n].cur = space[p].cur;
space[p].cur = n;
}
return true;
}
bool delete_list(SLL space, int S, int pos, int * pVal)
{
int i = 0;
int p = S;
while(0!=space[p].cur && i<pos-1)
{
p = space[p].cur;
i++;
}
if(i>pos-1 || 0==space[p].cur)
{
return false;
}
int q = space[p].cur;
*pVal = space[q].data;
space[p].cur = space[q].cur;
free_S(space, q);
return true;
}
int locate_list(SLL space, int S, int val)
{
int locate = 1;
int p = space[S].cur;
while(p && val!=space[p].data)
{
p = space[p].cur;
locate++;
}
if(0 == p)
{
return p;
}
else
{
return locate;
}
}
静态链表的讲解和实现就到此为止了,其参照的是严蔚敏《数据结构 C语言描述》,更多的数据结构及其基本操作的实现代码请参照我的github网站:https://github.com/SQL-JQC/DataStructure。