如何删除单链接列表中的节点,只有一个指针指向要删除的节点?
[开始和结束指针未知,可用信息是指向应删除的节点的指针]
答案 0 :(得分:17)
您可以在不获取上一个节点的情况下删除节点,方法是模拟以下节点并删除该节点:
void delete(Node *n) {
if (!is_sentinel(n->next)) {
n->content = n->next->content;
Node *next = n->next;
n->next = n->next->next;
free(next);
} else {
n->content = NULL;
free(n->next);
n->next = NULL;
}
}
如您所见,您需要专门处理最后一个元素。我正在使用一个特殊节点作为标记节点来标记content
和next
为NULL
的结尾。
更新:行Node *next = n->next; n->next = n->next->next
基本上会对节点内容进行洗牌,并释放节点:您在以下位置获取对节点B的引用的图像:
A / To be deleted
next ---> B
next ---> C
next ---> *sentinel*
第一步是n->content = n->next->content
:将以下节点的内容复制到要“删除”的节点:
A / To be deleted
next ---> C
next ---> C
next ---> *sentinel*
然后,修改next
点:
A / To be deleted
next ---> C /----------------
next ---| C |
next ---> *sentinel*
实际上释放了以下元素,进入最后一个案例:
A / To be deleted
next ---> C
next ---> *sentinel*
答案 1 :(得分:16)
不可能。
有些黑客可以模仿删除。
但是这些都不会实际删除指针所指向的节点。
如果你有外部指针,那么删除跟随节点并将其内容复制到要删除的实际节点的流行解决方案会产生副作用指向列表中的节点,在这种情况下,指向以下节点的外部指针将变为悬空。
您可以在SO here上找到一些讨论。
答案 2 :(得分:4)
此类限制下唯一的明智和安全的选项是标记已删除的节点而不实际取消链接,将其推迟到以后的时间。