您的位置:首页 > 移动开发

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

2013-11-11 17:37 363 查看
在阅读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节点指针。

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐