我是德国计算机科学专业的学生。我的教授用了下面的问题来思考:
'给定对单个链表中的节点的引用(不是最后一个节点)。给出一个算法,从列表中删除该元素,该元素具有O(1)复杂度,同时保持完整性。
我想到了这一点,但我很确定,没有这样的算法。因为它是单个链表,所以必须遍历列表中的每个节点,直到到达应该删除的节点,因为您必须在删除之前修改节点中的下一个指针。这将导致O(n)复杂性。
我错过了什么吗?
答案 0 :(得分:24)
这取决于节点是否可变(值)。
如果你可以用节点做你喜欢的事情,那么是的一种方式:
toDelete.value = toDelete.next.value
toDelete.next = toDelete.next.next
toDelete
中的所有信息现已被旧toDelete.next
中的信息覆盖。 (根据平台的不同,您可能需要释放旧的toDelete.next
- 这意味着保留一个临时引用。当然,如果其他人仍然引用它,那就不好了。在Java / C#中你是' d只是忽略它。)
我试图找出一种暗示它而不放弃它的方法,但它有点棘手......
它确实依赖于这不是列表中的最后一个节点。
答案 1 :(得分:8)
未完全考虑删除节点,但您可以将下一个节点的数据复制到当前节点并删除下一个节点:
// pseudocode:
this.data = next.data;
var temp = this.next;
this.next = next.next;
delete temp;
答案 2 :(得分:3)
如果节点是内存中的基本结构,则可以将“下一个”节点的内容复制到已删除节点的内存位置,并释放“下一个”节点所在的内存。
答案 3 :(得分:2)
是。你保留作为迭代指针,指向前一个列表的下一个指针的指针。
walk = &head;
while (!match(*walk)) {
walk = &walk[0]->next;
if (!*walk) return ;
}
*walk = walk[0]->next;
答案 4 :(得分:2)
假设您有指向要删除的节点的指针。将下一个值复制到当前节点。将当前指针替换为下一个指向的节点。
答案 5 :(得分:2)