删除单链表中的节点

文章详细解析了Linus提出的高效单链表节点删除方法,通过合理利用指针特性,简化了代码逻辑,避免了判断头节点的繁琐步骤,实现了灵活、高效的节点移除。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近看到Linus在采访中提到一种删除单链表中节点的方法,并说不懂这种方法的人都不理解指针,原话如下:

At the opposite end of the spectrum, I actually wish more people understood the really core low-level kind of coding. Not big, complex stuff like the lockless name lookup, but simply good use of pointers-to-pointers etc. For example, I’ve seen too many people who delete a singly-linked list entry by keeping track of the “prev” entry, and then to delete the entry, doing something like

if (prev)
prev->next = entry->next;
else
list_head = entry->next;

and whenever I see code like that, I just go “This person doesn’t understand pointers”. And it’s sadly quite common.


People who understand pointers just use a “pointer to the entry pointer”, and initialize that with the address of the list_head. And then as they traverse the list, they can remove the entry without using any conditionals, by just doing a “*pp = entry->next”.

So there’s lots of pride in doing the small details right. It may not be big and important code, but I do like seeing code where people really thought about the details, and clearly also were thinking about the compiler being able to generate efficient code (rather than hoping that the compiler is so smart that it can make efficient code *despite* the state of the original source code).

其实大神说的这种方法的好处就是: 在删除节点时,不用区别该节点是否是链表的第一个节点,具体实现代码如下:

 1 //定义最简单的链表结构
 2 typedef struct node
 3 {
 4     int value;
 5     struct node* next;
 6 }Node;
 7  
 8 Node** pp = &list_head;
 9 Node* entry = list_head;
10  
11 //假设要删除的节点值是9
12 while(entry->value != 9)
13 {
14     //每次迭代都将next变量的地址保存到pp中
15     //next是指针变量,故它的地址就是地址的地址了,即Node**
16     pp = &entry->next;
17     entry = entry->next;
18 }
19  
20 //将前置节点的next值指向下一个节点
21 *pp = entry->next;

各变量内容的变化如下:

内存地址:0x1               0x2                       0x4              0x8
        list_head=0x2     node1(value:10,           node2(value:9,   node3(value:8)
                                next变量的内存地址:
                                0x3                       0x5              0x9
                                next:0x4)                 next:0x8         next:NULL
 
迭代过程:
pp=0x1
entry=0x2
 
pp=0x3
entry=0x4
 
查找到要删除的节点:
*pp=0x8 => 0x2            
           node1(value:10,
                 0x3      
                 next:0x4 => 0x8)

这样,无论需要删除的是node1(头节点)还是普通节点,都不需要判断前置节点是否为头节点的指针。

转载于:https://www.cnblogs.com/liupengblog/p/4649004.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值