简体   繁体   English

将LinkedList节点设置为null

[英]Setting LinkedList nodes to null

I came across this problem earlier, in a coding book. 我之前在编码书中遇到过这个问题。

"Implement an algorithm to delete a node in the middle of a singly linked list, given only access to that node." “实现一种算法来删除单链表中间的节点,只允许访问该节点。”

The solution given in the book is this: 书中给出的解决方案是这样的:

public static boolean deleteNode(LinkedListNode n) {
    if (n == null || n.next == null) {
        return false; // Failure
    }
    LinkedListNode next = n.next;
    n.data = next.data;
    n.data = next.data;
    n.next = next.next;
    return true;
}

Which is a good solution, of course, being O(1). 当然,这是一个很好的解决方案,是O(1)。 The book notes this at the end, though. 不过,这本书最后指出了这一点。

"Note that this problem cannot be solved if the node to be deleted is the last node in the linked list". “请注意,如果要删除的节点是链表中的最后一个节点,则无法解决此问题”。

Am I missing something obvious here? 我错过了一些明显的东西吗? Why couldn't I just, say, put a check in the method before the body to check if n.next was equal to null, and if so, just set n to be null and return true? 为什么我不能只是在主体之前检查方法,检查n.next是否等于null,如果是,只需将n设置为null并返回true? Is there any reason I can't just do that? 有什么理由我不能这样做吗?

What this code is really doing is copying the next node into the given node. 这段代码真正做的是将下一个节点复制到给定节点。 The net effect is as if the current node is deleted, but really it's just being overridden with the next node. 净效果就好像当前节点被删除一样,但实际上它只是被下一个节点覆盖了。

That is, say you're deleting B in this list: 也就是说,你要删除此列表中的B

A -> B -> C -> D

The resulting list looks like this: 结果列表如下所示:

                 +------+
A -> B(Ccopy) ---+   C -+-> D

Now you can't do this to node D because there is no next node to copy. 现在,您无法对节点D执行此操作,因为没有要复制的下一个节点。

Why couldn't I just, say, put a check in the method before the body to check if n.next was equal to null, and if so, just set n to be null and return true? 为什么我不能只是在主体之前检查方法,检查n.next是否等于null,如果是,只需将n设置为null并返回true? Is there any reason I can't just do that? 有什么理由我不能这样做吗?

Setting n to null won't do anything. n设置为null将不会执行任何操作。 n is just a reference to the list node being deleted. n只是对要删除的列表节点的引用。 If you change n , you don't actually change anything on the list. 如果更改n ,则实际上不会更改列表中的任何内容。 For example, say you wanted to delete D in that same list. 例如,假设您要在同一列表中删除D It looks like this: 它看起来像这样:

               n
               |
               v
A -> B -> C -> D

If you set n to null, the end result is this: 如果将n设置为null,则最终结果如下:

               n---> null


A -> B -> C -> D

Note that nothing on the list changed at all. 请注意,列表中没有任何内容发生变化。

The only way to delete D in this case would be to modify C.next to point to null. 在这种情况下删除D的唯一方法是修改C.next指向null。 That is, you want this: 也就是说,你想要这个:

              +----> null
A -> B -> C --+ D

This requires modifying C , though, and in a singly linked list, you have no easy way to access C from D . 这需要修改C ,但在单链表中,你没有简单的方法从D访问C You'd have to search from the start of the list until you find the node x such that x.next == D . 您必须从列表的开头搜索,直到找到节点x ,使得x.next == D

So suppose you've the last node n , with n-1 (the previous node) and p (reference to last node) pointing to it: 所以假设你有最后一个节点nn-1 (前一个节点)和p (引用最后一个节点)指向它:

[n - 1] --> [n] <-- p

The reference you've is p . 您的参考是p And you've to delete the node n , pointed by p . 你要删除节点n ,由p指出。 If you set p to null , you don't de-reference [n - 1] pointer. 如果将p设置为null ,则不取消引用[n - 1]指针。 That still points to [n] node. 这仍然指向[n]节点。 So, that means, the node [n] is not really detached from the linked list. 因此,这意味着,节点[n]并未真正与链接列表分离。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM