递归遍历单链表插入元素时为何要给head->next赋值而非head
核心原因是函数形参的作用域和值传递规则
- 首先明确C语言的参数传递规则:所有参数都是值传递,哪怕是指针参数也不例外。你在函数里拿到的
head是实参的拷贝,属于当前函数的局部变量,仅在当前函数栈帧生效。 - 你写
head->next = insert(num, head->next)的时候,是修改head指针指向的节点的next成员,这个操作是直接修改原链表节点所在的堆/栈内存的内容,修改结果会保留在原链表结构中,能把递归返回的新子链表正确挂接到当前节点后面,保证链表完整。 - 如果你写
head = insert(num, head->next),只是修改了当前函数内局部变量head的指向,既不会修改原链表中当前节点的任何内容,也不会影响上层调用的指针指向,等当前函数返回后这个修改直接失效,会导致插入的节点没有被正确挂到原链表上,整个链表结构断裂,插入操作无效。
示例验证
比如你要在链表1 -> 3 -> 4中插入数值2:
- 第一层调用
head指向节点1,2>1的数值,进入递归,将head->next(即指向3的指针)作为参数传入下一层 - 第二层调用
head指向节点3,2<3的数值,调用addNewNode返回新节点2 -> 3的头指针 - 回到第一层调用:
- 如果是
head->next = 返回值:节点1的next会被改为指向新节点2,最终链表为1 -> 2 -> 3 -> 4,插入成功 - 如果是
head = 返回值:只是把第一层的局部变量head从指向1改成指向2,节点1的next还是指向原来的3,插入的2根本没有接入原链表,返回后原链表还是1 -> 3 ->4,插入失败
- 如果是
注:你给出的代码片段里判断条件
num <= head->next属于明显笔误,正常应该是head->next == NULL || num <= head->next->data或者num <= head->data,否则是非法的指针比较,运行会触发异常,但这个问题不影响两种写法的本质差异。
内容的提问来源于stack exchange,提问作者chubberson
相关产品推荐
相关产品推荐

