利用二级指针删除单向链表——笔记

今天看到这篇Linus:利用二级指针删除单向链表,作个笔记。

关于在单向链表中删除一个指定的节点,通常有两个易错点

  1. 找到指定节点删除时,忘了备份这个节点里指向下一个节点的指针。
  2. 没有特殊处理删除第一个节点的情况。

 

01//通常的写法
02 typedef struct node
03{
04     struct node * next;
05     ....
06} node;
07   
08 typedef bool (* remove_fn)(node const * v);
09   
10// Remove all nodes from the supplied list for which the
11// supplied remove function returns true.
12// Returns the new head of the list.
13node * remove_if(node * head, remove_fn rm)
14{
15     for (node * prev = NULL, * curr = head; curr != NULL; )
16     {
17         node * const next = curr->next;
18         if (rm(curr))
19         {
20             if (prev)
21                 prev->next = next;
22             else
23                 head = next;
24             free(curr);
25         }
26         else
27             prev = curr;
28         curr = next;
29     }
30     return head;
31}
01//Linus所说的利用二级指针的写法。
02 void remove_if(node ** head, remove_fn rm)
03{
04     for (node** curr = head; *curr; )
05     {
06         node * entry = *curr;
07         if (rm(entry))
08         {
09             *curr = entry->next;    //分离要删的节点
10             free(entry);   //回收内存
11         }
12         else
13             curr = &entry->next;   //->符号优先于&
14     }
15}

第二种写法使用了一个二级指针指向那个指向node节点的指针。关于这个实现,那个文章里已经说的很清楚了。这里只是记录一下对于这个实现的看法。

二级指针的关键在于:二级指针让head指针和next指针在某个特点上处于同一水平。head指针和next最大的不同点是next指针能被别的指针操作。因为next指针属于node结构体中,所以指向node结构体的指针可以携带操作next指针。而head指针没有,没有指针指向它,要修改head的值或者读取head,需要在代码中写明head。而二级指针就解决这个问题,这也就体现了什么是指针。这就是为什么linus说用第一种写法的人不懂指针。因为指针的强大之处在于它能指向任何东西,包括另一个指针。让一个固定了变量名的变量(甚至是一个函数)能作为一个值一样被传递。

是不是必须用二级指针呢?我表示如果单纯为了去掉head指针这个麻烦,我最简单的想法是可以让head指针实体化,即让head先指向一个没用的节点,再让这个节点的next指向链表头节点。

转载请注明:旅途@KryptosX » 利用二级指针删除单向链表——笔记

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值