1、链表的定义
链表分为两种:动态链表和静态链表。
链表中结点的分配和回收(即释放)是由系统提供的标准函数malloc和free动态实现的,称之为动态链表。
而通过定义一个较大的结构体数组来作为备用结点空间(即存储池),每个结点应至少含有两个域:data域和cursor域;data域用来存放结点的数据信息,cursor域(我们有时也称之为指针,通常叫游标)指示其后继结点在结构数组中的相对位置(即数组下标)。结构体数组的第0个分量可以设计成表的头结点,头结点的next域指示了表中第一个结点的位置。表中当前最后一个结点的域为0,表示静态单链表的结束。我们把具有如上特征或近视特征的结构体数组(也称作单链表)叫做静态单链表。
2、链表举例
a)动态链表
如果一个结构体类型的某些成员是该结构体类型的变量、数组或指针,则称之为递归结构,也叫自嵌套结构。我们这里便是一个应用。
typedef struct node
{ int data;
struct node *next;
} Dnode,DtNode[Maxsize];
图例见图1。
关于动态链表的操作,见“链表操作部分”:
http://blog.163.com/zhoumhan_0351/blog/static/399542272009322111214197/
b)静态链表
#define Maxsize 100//可要是其它数
typedef struct
{
ElemType data;
int cursor;
}Component, StaticList[Maxsize];
如图2中所示。
图2 静态链表图示,第二栏为游标
经过多次插入和删除后,会造成静态链表的“假满”,即表中有很多空闲空间,但却无法再插入元素。造成这种现象的原因是未对已删除的元素所占的空间进行回收。我们可以将所有未被分配的结点空间以及因删除操作而回收的结点空间用游标(cursor)链成一个备用静态链表。当进行插入操作时,先从备用链表上取一个分量来存放待插入的元素,然后将其插入到已用链表的相应位置。当进行删除操作时,则将被删除的结点空间链接到备用链表上以备后用。
关于静态链表的操作,见“基数排序”这一部分:
http://blog.163.com/zhoumhan_0351/blog/static/39954227200992125253428/
2、头结点,头指针,头元素
为了方便链表的操作,我们通常在单链表的第一个结点之前附设一个结点,称为头结点。头结点的数据域可以不存储数据,也可存储一些线性表相关的附加信息。头结点的指针域存储指向第一个结点(我们称之为头元素)的指针,单链表的头指针指赂头结点。
如图中所示:
图1 动态链表图示