头结点概念
首先,单链表是由表头指针所唯一确定的,因此,单链表可以用头指针的名字来命名,若头指针名为 L,则称该链表为表 L 首元结点是指链表中存储第一个数据元素的结点 头结点是在首元结点之前设的一个结点,其 next 指针指向首元结点,其据域可以不存储任何信息。 但头指针永远指向的是链表中第一个结点的指针,有头结点则指向头结点,无则指向首元结点。头指针不可变,要遍历链表应另设结点指针增加了头结点后,首元结点的地址保存在头结点的指针域中,则对链表的第一个数据元素的操作(插入、删除)与其他的数据元素相同,无需进行特殊处理。 且便于对空表和非空表的统一处理,增加头节点以后,无论链表是否为空,头指针都是非空指针
注意:头结点是第 0 个结点
插入、删除操作
有头结点
/* 插入操作 */
void Insert( List L, ElementType X, int i)
{
List s, p; /*p表示插入点前一个结点,s表示插入的结点*/
p=Find(i-1,L);
if ( p==NULL )
printf("插入位置参数错误\n"); /* P所指的结点不在L中 */
else
{
s = (List)malloc(sizeof(struct LNode)); /* 申请、填装结点 */
s->Data = X;
s->Next = p->next;
p->Next = s;
}
}
/* 删除操作 */
void Delete( List L, int i)
{
List p,s; /*p表示删除点前一个结点,s表示待删除的结点*/
p=Find(i-1,L); /* 查找s的前一个结点 */
if(p||p->next)
printf("删除位置参数错误\n");
else
{
s=p->next;
p->Next = s->Next;
free(s); /* 将s位置的结点删除 */
}
}
无头结点
/* 插入操作 */
List Insert( List PtrL, ElementType X, int i) /*无头结点则要判断是否为插入第一个结点*/
{
List p,s; /*p表示插入点前一个结点,s表示插入的结点*/
if(i= =1) /*若插入位置为第一个*/
{
s=(list)malloc(sizeof(struct LNode)); /* 申请、填装结点 */
s->data=X;
s->next=PtrL;
return s; /*s变为新头指针*/
}
else
{
p=Find(i-1,PtrL);
if ( p==NULL )
printf("插入位置参数错误\n");
else
{
s = (list)malloc(sizeof(struct LNode)); /* 申请、填装结点 */
s->Data = X;
s->Next = p->next;
p->Next = s;
return PtrL;
}
}
}
/* 删除操作 */
List Delete( List PtrL,int i)
{
List p,s; /*p表示删除点前一个结点,s表示待删除的结点*/
if(i= =1) /*若删除第一个结点,头结点为第0结点*/
{
s=PtrL;
if(PtrL) PtrL=PtrL->next; /*若链表不为空,换头指针*/
else return NUll;
free(s);
return PtrL;
}
else
{
p=Find(i-1,PtrL);
if(p||p->next)
printf("第%d个结点不存在,i);
else
{
s=p->next;
p->next=s->next;
free(s); /* 将s位置的结点删除 */
return PtrL;
}
}
}