用于删除具有O(1)复杂度的单个链表中的一个元素的算法

时间:2009-04-27 15:08:00

标签: algorithm linked-list computer-science big-o

我是德国计算机科学专业的学生。我的教授用了下面的问题来思考:

'给定对单个链表中的节点的引用(不是最后一个节点)。给出一个算法,从列表中删除该元素,该元素具有O(1)复杂度,同时保持完整性。

我想到了这一点,但我很确定,没有这样的算法。因为它是单个链表,所以必须遍历列表中的每个节点,直到到达应该删除的节点,因为您必须在删除之前修改节点中的下一个指针。这将导致O(n)复杂性。

我错过了什么吗?

6 个答案:

答案 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)