双向链表中要删除的节点的成员变量要初始化为null的原因

The reason why the member variable of the node to be deleted from the doubly linked list should be initialized to null

public class Node<E> {
    E data;
    Node<E> left;
    Node<E> right;
}

下面的代码从双向链表中删除特定索引处的节点。在代码的最后,要删除的节点的left、right、data都要初始化为null。这是一个必要的过程吗?如果不初始化为 null

会发生什么
public void remove(int index) {

    Node foundNode = findNode(index);
    Node leftNode = foundNode.left;
    Node rightNode = foundNode.right;

    leftNode.right = rightNode;
    rightNode.left = leftNode;

    foundNode.left = null;
    foundNode.right = null;
    foundNode.data = null;

    --size;
}

完全清楚:new Node() 会将节点字段 leftright 初始化为 null

remove 将删除的 foundNode 的所有字段设置为 null 误入歧途的 尝试 优化 垃圾回收。

您没有创建延迟对象(其他已删除的节点),没有内存泄漏。作为垃圾收集器可以处理无法访问的对象的集合。

注意:对于其他语言,这可能不成立。

在“正常”情况下,最后三个带 null 的赋值是不需要的。当函数完成时,它的局部变量被释放,因此通常不会有任何对 foundNode.

引用的节点的引用

然而,可能是在其他代码中——不是这个函数的一部分——仍然有一个引用那个节点的变量,然后指示这个节点不再是函数的一部分也不是那么糟糕一个(更长的)列表。通过将 leftright 设置为 null,为每个 node 维护以下不变量:

  1. 或者node.left == null,或者
  2. node.left.right == node

...类似地:

  1. 或者node.right == null,或者
  2. node.right.left == node

如果我们不设置 foundNode.left = null,则不会恢复上述不变量,如果在函数执行上下文之外仍然存在对 foundNode 的引用,这可能是一个问题。

至于foundNode.data = null:那真的没有必要。如果foundNode引用的节点没有被其他地方引用,那么foundNode可以被垃圾回收。如果也没有其他对其数据的引用,那么该数据也可以被垃圾收集。将此 属性 设置为 null 并不会真正改变该过程。其次,如果我们考虑仍然可能有对该节点的引用的情况,那么 null 可能是在整个算法中 实际上 有意义的数据,因此将其设置为null 不保证以明确的方式将其标记为“已删除”节点。