* 今天在酷壳上看到linus提到的使用及指针来删除单链表中的节点,感觉比常见做法要好很多,所以记录一下。方便自己以后查看。*
为了进行对比先写一个自己在进行单链表节点删除时操作;
链表格式如下:
struct node
{
struct node *next;
int data;
};
typedef bool(*remove_fun)( const struct node *node, int value );
bool rm( const struct node *node, int value )
{
return ( node->data == value )?true:false;
}
第一种方法:采用一级指针;
//删除链表中 节点值 == value 的节点;
struct node * remove( struct node *head, int value, remove_fun rm )
{
for( struct node *prev = NULL, *cur = head; cur != NULL; )
{
struct node *next = cur->next;
if( rm(cur, value) )
{
if( prev )
prev->next = next;
else
head = next;
free( cur );
}
else
prev = cur;
cur = cur->next;
}
return head;
}
以上做法是一种常用的采用一级指针来进行链表节点的删除,并在操作中考虑了要删除的节点位置,分三种情况:
第一种:当删除的节点是链表中的第一个节点时;
第二种:当删除的节点是最后一个节点时;
第三种:当删除链表中间的节点;
并且需要使用变量prev来保存前一个节点,同时由于在删除第一个节点时其链表的头指针已经发生变化,所以要通过返回值来告诉调用函数;
可以看到以上代码能实现功能,但是考虑情况较多,代码不够简洁。
第二种方法:采用二级指针;
void remove( struct node **head, int value, remove_fun rm )
{
for( struct node **cur = head; *cur != NULL; )
{
struct node *entry = *cur;
if( rm(entry, value) )
{
*cur = entry->next;
free(entry);
}
else
cur = &entry->next;
}
}
看到上面的这段代码感觉真是高手之作啊,写的真是逻辑简洁,将所有的情况都包含其中。以此记下,方便以后使用与查阅。