创建单链表的过程是一个动态生成链表的过程,从“空表”的初始状态起,依次建立各元素结点并逐个插入链表。
所以单链表整表创建的算法思路如下:
-声明一结点p和计数器变量i;
-初始化一空链表L;
-让L的头结点的指针指向NULL,即建立一个带头结点的单链表;
-循环实现后继结点的赋值和插入。
头插法的核心思想是:
s->next=L->next;
L->next=s;
如图:头结点是*L。。。头结点一般储存单链表的长度的信息。
首节点是(*L)->next。。。是储存元素的值和下一个元素的位置的信息。
现在我想插入一个新的节点p。。。
第一:新节点的指针域指向首节点,开始时指向为null。
第二:修改头结点的指针域,使其指向新节点p。
重点语录
链表是以地址来发现元素的
链表读一个数据,系统就申请一个存储单元。二者是同步的
void CreatListHead(List *L) //头插法建立链表
{
List *s; //不用像尾插法一样生成一个终端节点。
L->next = NULL;
for (int i = 0; i < 10; i++)
{
s = (struct List*) malloc(sizeof(struct List));
s->data = i;
s->next = L->next; //将L指向的地址赋值给S;//头插法与尾插法的不同之处主要在此,
//s所指的新节点的指针域next指向L中的开始节点
L->next = s; //头指针的指针域next指向s节点,使得s成为开始节点。
}
}
尾插法:
r始终指向尾部,称为终端结点
void CreatListTail(List *L) //尾插法建立链表
{
List *s, *r;//s用来指向新生成的节点。r始终指向L的终端节点。
r = L; //r指向了头节点,此时的头节点是终端节点。
for (int i = 0; i < 10; i++)
{
s = (struct List*) malloc(sizeof(struct List));//s指向新申请的节点
s->data = i; //用新节点的数据域来接受i
r->next = s; //用r来接纳新节点
r = s; //r指向终端节点
}
r->next = NULL; //元素已经全部装入链表L中
//L的终端节点指针域为NULL,L建立完成
}
整表删除ClearList()
单链表整表删除的算法思路如下:
-声明结点p和q;
-将第一个结点赋值给p,下一结点赋值给q;
-循环执行释放p和将q赋值给p的操作;
Status ClearList(LinkList *L)
{
LinkList p, q;
p = (*L)->next;//p指向第一个结点
while(p)//循环至链尾
{
q = p->next;//将下一个结点赋值给q作为中间变量
free(p);//释放第一个
p = q;//将中间变量传给p
}
(*L)->next = NULL;//头结点指针域置空
return OK;
}