《算法设计手册》链表节点删除代码的指针操作逻辑疑问
链表节点删除代码疑问解答
首先纠正你梳理逻辑中的一个核心错误:C语言的函数参数是值传递,item_ahead函数的形参l是外部实参*l的副本,函数内部对形参l的修改完全不会影响到delete_list里的*l的值,所以你认为“调用item_ahead后*l和pred指向同一地址”的结论不成立,*l在你主动赋值前,一直指向原来的链表头。
问题1解答
pred返回NULL的有效场景(排除空链表无节点可删的情况)只有一个:你要删除的节点*x就是当前链表的头节点。
因为item_ahead的逻辑是查找目标节点x的前驱节点,而头节点没有前驱,所以找不到只能返回NULL。delete_list开头就把p赋值为*l(也就是原链表头节点),这时候要删除头节点,就需要把外部的链表头指针指向原头节点的下一个节点,所以*l = p->next就是做这个操作。
你的理解错误有两点:
- 误以为
item_ahead会修改外部的*l,实际上*l一直保留着原头节点的地址,没有被修改 - 如果写成
*l = p,等于把原头节点地址又赋值回去,相当于没做修改,头节点根本没有被删掉,完全不符合预期。
问题2解答
splice out of list的含义是「将目标节点从链表的链路中移除」,也就是调整链表的指针关系,让目标节点不再属于链表的有效遍历序列,为后续释放节点内存做准备。
问题3解答
*l是二级指针,指向的是调用方传入的链表头指针变量的地址,对*l的修改会直接改变调用方持有的头指针的取值,并不是“后续不会被使用”:
比如调用方的代码是list *my_head = 创建链表(); delete_list(&my_head, &要删的头节点);,修改*l就是直接修改my_head的取值,让它指向删除头节点后的新表头,避免调用方后续使用my_head时访问已经被释放的内存,出现野指针错误。
内容的提问来源于stack exchange,提问作者JB-Franco
相关产品推荐
相关产品推荐

