c语言单链表:有头结点和无头结两种列表的区别以及创建和输出的区别

头指针和头节点的区别:

头指针:

  1. 头指针是指向第一个结点的指针,若链表有头结点,则是指向头结点的指针
  2. 头指针具有标识作用,所以常用的头指针冠以链表的名字(指针变量的名字)
  3. 无论链表是否为空,头指针均不为空
  4. 头指针是链表的必要元素

头结点:

  1. 头结点是为了操作的统一和方便而设立的,放在第一个元素的结点之前,其数据域
    一般无意义(但也可以存放链表的长度)
  2. 有了头结点,对应第一元素结点前插入结点和删除第一结点其操作与其他系欸但那的操作就统一了


带头结点链表图示:
在这里插入图片描述
#若不头结点,头指针指向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);
	}

说明本文图片来源于网络

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小普罗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值