单链表为什么要设置头结点
转自https://www.cnblogs.com/youxin/p/3279391.html
链表中第一个结点的存储位置叫做头指针,那么整个链表的存取就必须是从头指针开始进行了。之后的每一个结点,其实就是上一个的后继指针指向的位置。
这里有个地方要注意,就是对头指针概念的理解,这个很重要。“链表中第一个结点的存储位置叫做头指针”,如果链表有头结点,那么头指针就是指向头结点数据域的指针。画一个图吧。
头指针就是链表的名字。头指针仅仅是个指针而已。
- 头结点是为了操作的统一与方便而设立的,放在第一个元素结点之前,其数据域一般无意义(当然有些情况下也可存放链表的长度、用做监视哨等等)。
- 有了头结点后,对在第一个元素结点前插入结点和删除第一个结点,其操作与对其它结点的操作统一了。
- 首元结点也就是第一个元素的结点,它是头结点后边的第一个结点。
- 头结点不是链表所必需的。
- 是的,对于头指针,我们也可以有相应的理解了。
- 在线性表的链式存储结构中,头指针是指链表指向第一个结点的指针,若链表有头结点,则头指针就是指向链表头结点的指针。
- 头指针具有标识作用,故常用头指针冠以链表的名字。
- 无论链表是否为空,头指针均不为空。头指针是链表的必要元素。
-
单链表也可以没有头结点。如果没有头结点的话,那么单链表就会变成这样:
typdef struct LNode{
int data,
LinkList *next;
}LNode,*LinkList;
LinkList head=new LNode();
head->next=null;
插入n个元素
LinkList p=head;
for(int i=0;i<n;i++)
{
LinkList q=new LNode();
q->data=i; q->next=null;
p->next=q;
}
为了使空链表与非空链表处理一致,我们通常设一个头结点。
转的一篇文章:
单链表带头结点&不带头结点
void InitList(Node **head){
Node *r=*head,*s;
int a;
while(scanf("%d",&a)){
if(a!=0){
s=(Node *)malloc(sizeof(Node));
s->value=a;
r->next=s;
r=s;
}
else{
r->next=NULL;
break;
}
}
}
Node *r=head,*s;
... //下面的都一样
}
Node *p,*t; /*p工作指针,t临时指针*/
int a,i=1;
while(scanf("%d",&a)){
if(a!=0){
t=(Node *)malloc(sizeof(Node));
t->value=a;
if(i==1){
*head=t;
}
else{
p->next=t;
}
p=t;
}
else{
p->next=NULL;
break;
}
i++;
}
}
posted on 2018-09-25 16:15 Magic_chao 阅读(...) 评论(...) 编辑 收藏