当仅给出指向该节点的指针时,从单个链表中删除该节点
这是我在采访中被问到的一个问题。
“内存中有一个单链表。你要删除一个节点。你需要编写一个函数来删除该节点,该函数只需要删除节点的地址作为输入,而不需要其他任何东西(包括头)”
我给出的答案类似于下面帖子中的答案——将下一个节点的内容复制到要删除的节点并删除下一个节点。
但是面试官又问我,如果我传递最后一个节点的地址怎么办?我告诉他,由于下一个节点将为 NULL,因此将该 NULL 连同下一个节点的地址复制到数据字段中,该节点也是 NULL。然后他告诉我会有一个悬空指针的问题......我有点不明白。有人可以解释一下这个问题吗?有一个通用的解决方案吗?
更新(两天后):一点补充。考虑到链表末尾没有特殊节点。最后一个节点指向 NULL,如果该节点作为输入给出,如何使前一个节点指向 NULL。或者说这是不可能的?
简单地说:如果一个节点作为函数的输入,如何使引用它的指针指向 NULL
This is a question posed to me in an interview.
"A single linked list is there in the memory. You have to delete a node. You need to write a function to delete that node, which takes only the address of the node to be deleted as input and nothing else(including head)"
I gave the answer similar to the one answered in the below post -- Copying the contents of the next node into the node to be deleted and deleting the next one.
Deleting a middle node from a single linked list when pointer to the previous node is not available
But the interviewer asked me again, what if I pass the address of the last node. I told him, since the next will be a NULL, copy that NULL into the data field along with the address to the next node which is also NULL. Then he told me there will be a problem of dangling pointers... which I didn't understand a bit. Can some one please throw light into this problem ? Is there a generic solution to this ?
Update (Two days later) : A little bit additional. Considering there is no special node at the end of the list. And the last node points to NULL and if that node is given as input, how to make the before last node point to NULL. Or is it impossible ?
Simply put : If a node is given as input to a function, how to make the pointer that references it, point to NULL
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
步骤:
功能:
Steps:
Function:
悬空指针:
在您的答案中,要删除给定节点,您实际上删除了下一个节点,该节点可能由指针引用。这就是悬空指针问题的产生方式。
(1) 正如您在注释中所澄清的那样,该列表没有外部引用。
(2) 正如面试官所说,会出现悬空指针问题。
(1)和(2)不可能同时正确。这意味着某处存在误解。
关于删除最后一个节点:
我认为您混淆了这两件事:(1)指向 NULL 的指针 p,(2)数据字段中包含 NULL 的链表节点。
假设数据结构为
a -> b-> c-> d。将 NULL 写入 d 的数据字段不会神奇地使 c 在其
next
字段中拥有 NULL 指针。如果链表总是有一个永远不会被删除的特殊最后一个节点,您可以删除最后一个节点。例如,
a -> b-> c-> d-> LAST
其中 LAST 在其数据字段中有一个特殊值,表示它确实是最后一个元素。现在要删除 d,您可以删除 LAST 并将特殊值写入 d 的数据字段。也许这些正是你在面试时试图讲述的内容,在这种情况下,你和面试官之间一定存在一些沟通不畅。
Dangling Pointer:
In your answer, to delete the given node you actually delete the next node, which might be being referenced by a pointer. That's how dangling pointer problem arise.
(1) There are no outside references to the list, as you clarify in a note.
(2) Dangling pointer problem can arise, as the interviewer said.
Both (1) and (2) cannot be correct at the same time. Which means there is a misunderstanding somewhere.
About Deleting the Last Node:
I think you are confusing these two things: (1) A pointer p that points to NULL, (2) A linked list node that has NULL in its data field.
Suppose the data structure is
a -> b -> c -> d
. Writing NULL to d's data field will not magicly make c to have a NULL pointer in itsnext
field.You can delete the last node if the linked list always has a special last node that will never be deleted. For example,
a -> b -> c -> d -> LAST
where LAST has a special value in its data field that denotes it is really the last element. Now to delete d, you could delete LAST and write the special value in d's data field.Maybe these are exactly what you tried to tell during the interview, in which case there must have been some miscommunication between you and the interviewer.
然后应该在程序中检查给定节点是否是最后一个节点。
Then there should be a check in the program whether the given node is the last node or not.
如果还有其他元素指向下一个节点,这些元素将被复制到当前节点然后被删除,那么此操作将引入错误。因此,在您的回答中,您应该强调您的解决方案仅在没有对该列表的外部引用的情况下才有效。
仅当数据结构使用特定的“最后一个节点”元素进行扩充时,您的解决方案才适用于最后一个节点。 (如果您使用的是 Smalltalk,则可以编写
self come: nil
没有其他语言有类似的内容)不,如果存在对该列表的外部引用,则没有通用解决方案。我认为面试官想看看你是否真的对这个主题很了解,或者只是在重复记住的答案。
If there are other elements that are pointing to the next node which will be copied to the current node and then deleted, then this operation will introduce a bug. So in your answer you should have emphasized that your solution only works if there are no outside references to the list.
Your solution works with the last node only if the data structure is augmented with a specific "last node" element. (If you are using Smalltalk, you can write
self become: nil
No other language has anything similar)No, there is no generic solution if there are outside references to the list. I think the interviewer wanted to see whether you are really knowledgable in the subject matter or were just repeating a memorized answer.
也许您的链接列表遍历可能需要假设任何指向
null
的节点都是null
节点,无论其值如何......所以
d
是null
节点并且该节点不应被视为节点。这样您就可以节省使用特殊值的时间,因为它们在一般意义上是不正确的。除此之外,您将没有任何其他方式让前一个节点指向null
。Probably your link list traversing might need to assume that any node that points to
null
isnull
node regardless of the value...so
d
isnull
node and the node should not be considered as a node. this way you can save on using special values since they are not correct in a generic sense. other than that you will not have any other way for previous node to point tonull
.当给出最后一个节点时,不是将其删除,而是将其分配给虚拟节点,并且在显示数据时,我们可以检查 ptr->next 作为虚拟节点并在那里终止。
对于悬空指针,我相信当指针被释放(释放)时,它将成为悬空指针,因此在释放后将其分配为 NULL。
下面是我针对这个问题的代码片段:
When the last node is given, instead of deleting it, assign it to a dummy node and while displaying the data we can check for ptr->next as dummy node and terminate there.
In case of dangling pointer, I believe when the pointer is freed(deallocated), it will become dangling pointer and so after freeing assign it to NULL.
Below will be my code snippet for this Question:
假设:
deleteNode()
引用节点指针。没有 while 循环的简单解决方案。在deleteNode()中,if case处理头节点和中间节点的删除,else处理最后一个节点的删除。
Assumption:
deleteNode()
has reference to node pointer.Simple solution without a while loop. In
deleteNode()
, if case handles deletion of head and intermediate node and else handles deletion of last node.