【数据结构】无头节点链表插入节点

前言

最近做毕设时发现了一个问题,无头链表并不能通过结构体指针进行函数传参插入数据,这种方法只适用于附带头结点的链表,

错误示例

假设结构体为:

typedef struct link
{
	int data;
	struct link *next;
}Listnode

插入数据的函数为:

//错误示例
void fun(Listnode *head,int n)
{
	Listnode *cur=head;
	Listnode *tmp=(Listnode*)malloc(sizeof(Listnode));
	scanf("%d",&tmp->data);
	if(cur==NULL){
	cur=tmp;
	}
	else{
	 while(cur!=NULL)
	 {
	 	cur=cur->next;
	 }
	 cur->next=NULL;
	 }
}

主函数为:

//无头节点的链表创建
Listnode *head;
head=(Listnode*)malloc(sizeof(Listnode));
fun(head,4);

这样是行不通的,这种定义结构体指针传参的方法只可用于附带头结点的链表,对于无头节点链表不适用

附带头结点的链表创建是这样的:

Listnode *head;
head=(Listnode*)malloc(sizeof(Listnode));
head->next=NULL;

问题分析

经过一下午的冥想以及测试才明白,这种定义结构体指针函数数传参的方法,只适用于附带头结点的链表,因为认真学过C语言的都知道,函数传参的参数只是实参的拷贝(叫做形参),形参在函数执行完毕后便从栈内销毁,无法改变外部实参
如果想要改变外部形参,我们可以利用指针传递参数地址,例如:

void fun1(int *a,int *b)
{
	*a=*a+1;
	*b=*b+1;
}
fun(&a,&b);

由此可得,在上文中定义的函数void fun(Listnode *head,int n)只是传递的结构体指针头结点的形参,在函数里进行操作的只是头节点的一份拷贝,如果函数要对头结点数据域进行改变,并不会对函数外的链表头结点进行改变.
但是假如我们传入的是附带头结点的链表,那么就不需要对头结点进行赋值操作,只需对头结点指向的下面的节点进行操作
传入的头节点虽然是形参,无论是形参还是实参,它们next指针指向的空间都是相同的,但对于无头结点的链表我们就需要传入指针结构体的指针,将指针结构体的地址传入函数,这样才能真正改变这个指针结构体

正确代码

该代码通过定义二级指针,传入了指针结构体的地址,可对头节点进行更改

void add(Listnode** head_ptr) 
{
	float sr,so=0.01;
	int a;
    Ctf* new_ctf = (Ctf*) malloc(sizeof(Ctf));
    new_ctf->next = NULL;
    scanf("%d", &new_ctf->data); 
    if (*head_ptr == NULL)
	{
        *head_ptr = new_ctf;
    } 
	else 
	{
        Ctf *current = *head_ptr;
        while (current->next != NULL) 
		{
            current = current->next;
        }
        current->next = new_ctf;
    }
}

总结

印象中数构老师好像顺便讲过,后悔没仔细听

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Elitewa

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

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

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

打赏作者

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

抵扣说明:

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

余额充值