头指针和头节点的区别:
头指针:
- 头指针是指向第一个结点的指针,若链表有头结点,则是指向头结点的指针
- 头指针具有标识作用,所以常用的头指针冠以链表的名字(指针变量的名字)
- 无论链表是否为空,头指针均不为空
- 头指针是链表的必要元素
头结点:
- 头结点是为了操作的统一和方便而设立的,放在第一个元素的结点之前,其数据域
一般无意义(但也可以存放链表的长度) - 有了头结点,对应第一元素结点前插入结点和删除第一结点其操作与其他系欸但那的操作就统一了
,
带头结点链表图示:
#若不头结点,头指针指向a1
空链表图示:
链表的结点类型定义:
struct student{//定义学生结构类型
int length; //用于带头结点存放链表长度(当创建无头结点链表时,可以忽略此数据项)
int num;//学号
int score;//分数
struct student *next;//指针域:指向下一个结点
};
创建无头结点的链表:
```c
struct student *creat_link_table(int n)
{
int i;
struct student *head=NULL,*p1,*p2=NULL;//head:头指针,p2:尾指针,初值:NULL;
for(i=1;i<=n;i++)//建立n个结点的链表
{
if((p1=(struct student *)malloc(sizeof(struct student)))==NULL){
printf("不能分配存储块!\n");
exit(0);
}
p1->next=NULL;//令新节点指针域为NULL
printf("请输入第%d个学生学号及成绩:",i);
scanf("%d%d",&p1->num,&p1->score);
if(i==1)
head=p1;
else
p2->next=p1;//表尾连接心结点
p2=p1;//p2指向新的表尾结点
}
return head;//返回头指针
}
void main(){
int n,i;
struct student *head,*p;
printf("请输入需要创建链表的长度n:");
scanf("%d",&n);
head=creat_link_table(n); //用head接收返回的头指针
p=head; //头指针指向第一个结点(并非头结点),注意以含有头结点链表的区别,对比学习
for(i=0;p!=NULL;i++){
printf("第%d个学生的学号和成绩:\n");
printf("姓名 成绩\n");
printf("%d %d\n",p->num,p->score);
p=p->next;
}
}
创建有头节点的单链表并输出:
struct student *creat_link_table(int n){
int i;
struct student *head=NULL,*p1,*p2=NULL;
//p1为临时指针,主要用来开辟新的空间;p2起过度作用,主要用来使上一个指针与新开辟的空间p1连接起来
if((head=(struct student *)malloc(sizeof(struct student)))==NULL){
printf("不能成功分配存储空间!");
exit(0);
}
head->length=0; //头指针存放链表长度,并初始化为0
p2=head; //令p2=头指针,以便p2与开辟的新结点p1连接
for(i=1;i<=n;i++){ //创建长度为n的链表
if((p1=(struct student *)malloc(sizeof(struct student)))==NULL){
printf("不能成功分配空间!");
exit(0);
}
p1->next=NULL; //使p1指向空地址
printf("请输入第%d个学生的学号和成绩:\n",i);
scanf("%d%d",&p1->num,&p1->score);
p2->next=p1; //使p2连接新的结点p1;
p2=p1; //令p2=p1,让指针p2往前移
head->length++; //链表长度加1
}
return head;
}
void main(){
int n,i;
struct student *head,*p;
printf("请输入需要创建链表的长度n:");
scanf("%d",&n);
head=creat_link_table(n); //用head接收返回的头指针
p=head->next; //头结点不存放数据,所以p应指向头节点的下一个结点
for(i=0;p!=NULL;i++){
printf("第%d个学生的学号和成绩:\n");
printf("姓名 成绩\n");
printf("%d %d\n",p->num,p->score);
p=p->next;
}
printf("链表长度为: %d\n",head->length);
}
说明本文图片来源于网络