这是一个在采访中向我提出的问题 .
“内存中有一个链表 . 你必须删除一个节点 . 你需要编写一个删除该节点的函数,该节点只删除节点的地址作为输入而不包括任何其他节点(包括头部)”
我给出了类似于下面帖子中回答的答案 - 将下一个节点的内容复制到要删除的节点中并删除下一个节点 .
Deleting a middle node from a single linked list when pointer to the previous node is not available
但是面试官再次问我,如果我传递最后一个节点的地址怎么办 . 我告诉他,因为下一个将是一个NULL,将NULL复制到数据字段以及下一个节点的地址也是NULL . 然后他告诉我将会出现悬挂指针的问题......我对此并不了解 . 请问有人可以解决这个问题吗?这是一个通用的解决方案吗?
更新(两天后):再补充一点 . 考虑到列表末尾没有特殊节点 . 最后一个节点指向NULL,如果该节点作为输入,则如何使前一个节点指向NULL . 还是不可能?
简单地说:如果给一个节点作为函数的输入,那么如何使引用它的指针指向NULL
6 回答
悬挂指针:
在您的回答中,要删除给定节点,您实际上删除了可能被指针引用的 next 节点 . 这就是悬垂指针问题出现的原因 .
(1)正如您在备注中说明的那样,没有外部参考列表 . (2)面试官说,可能会出现悬垂指针问题 .
(1)和(2)都不能同时正确 . 这意味着某处存在误解 .
关于删除最后一个节点:
我认为你混淆了这两件事:(1)指向NULL的指针p,(2)在其数据字段中具有NULL的链表节点 .
假设数据结构是
a -> b -> c -> d
. 将NULL写入d's数据字段不会使c在其next
字段中具有NULL指针 .您可以删除永远不会删除的最后一个节点 if the linked list always has a special last node . 例如,
a -> b -> c -> d -> LAST
其中LAST在其数据字段中有一个特殊值,表示它实际上是最后一个元素 . 现在要删除d,你可以删除LAST并在d's数据字段中写入特殊值 .也许这些正是你在面试中试图说的,在这种情况下,你和面试官之间肯定会有一些误解 .
脚步:
将数据从节点(i 1)复制到节点(i)
将第二个节点(i 1)的NEXT复制到临时变量中 .
现在删除第二个节点(i 1)//它不需要指向前一个节点的指针 .
功能:
然后应该检查程序是否给定节点是否是最后一个节点 .
如果有其他元素指向将被复制到当前节点然后删除的下一个节点,则此操作将引入错误 . 因此,在您的回答中,您应该强调,只有在列表没有外部引用时,您的解决方案才有效 .
仅当数据结构使用特定的"last node"元素进行扩充时,您的解决方案才能使用最后一个节点 . (如果你使用的是Smalltalk,你可以写
self become: nil
没有其他语言有类似的东西)不,如果列表有外部引用,则没有通用解决方案 . 我认为面试官想知道你是否真的在这个主题上是知识渊博的,或者只是重复一个记忆回答 .
可能你的链接列表遍历可能需要假设任何指向
null
的节点都是null
节点,无论值是什么......所以
d
是null
节点,不应将该节点视为节点 . 这样你可以节省使用特殊值,因为它们在一般意义上是不正确的 . 除此之外,您将没有任何其他方式让前一个节点指向null
.