[Happy DSA] 删除单链表中任意一个节点的方法

本文介绍了一种高效地从单链表中删除指定值的所有节点的方法,通过使用节点指针的指针,该方法能够巧妙地处理包括头节点在内的所有情况。

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

在阅读c-algorithms代码时,又看到如下的代码(删除单链表中任意一个节点)

/* A singly-linked list */

struct _SListEntry {
     SListValue data;
     SListEntry *next;
};

int slist_remove_data(SListEntry **list, SListEqualFunc callback, SListValue data)
{
     SListEntry **rover;
     SListEntry *next;
     int entries_removed;

     entries_removed = 0;

     /* Iterate over the list.  'rover' points at the entrypoint into the
     * current entry, ie. the list variable for the first entry in the
     * list, or the "next" field of the preceding entry. */
    
     rover = list;

     while (*rover != NULL) {
         
          /* Should this entry be removed? */
         
          if (callback((*rover)->data, data) != 0) {               
               /* Data found, so remove this entry and free */
               next = (*rover)->next;
               free(*rover);
               *rover = next;
              
               /* Count the number of entries removed */
               ++entries_removed;
          } else {               
               /* Advance to the next entry */
               rover = &((*rover)->next);
          }
     }

     return entries_removed;
}

上面的函数实现不仅可以去除头节点,也可以去除中间的任意节点。它依赖的技巧就是节点指针的指针:用节点指针的指针来保存前面一个节点的next域的指针,从而在去除当前节点之前,可以将当前节点的下一个节点link/assign到那个保存的next指针域中。

我们通常的做法可能会区分对待头节点,并维护一个prev节点指针。

上面的方法巧妙并且通用的解决了上面的问题。
找到一张以前画的示意图(跟上面的代码变量定义有些出入):


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值