public class Node<E> {
E data;
Node<E> left;
Node<E> right;
}
The code below deletes a node at a specific index from a doubly linked list. At the end of the code, left, right, and data of the node to be deleted must all be initialized to null. Is this a necessary process? What can happen if you don't initialize to 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;
}
In "normal" circumstances the three last assignments with
null
are not needed. When the function completes, its local variables are deallocated, and so there will usually not be any reference to the node that was referenced byfoundNode
.However, it could be that in other code -- not part of this function -- there is still a variable that references that node, and then it is not that bad to indicate that this node is no longer part of a (longer) list. By setting
left
andright
tonull
, the following invariant is maintained for everynode
:node.left == null
, ornode.left.right == node
...and similarly:
node.right == null
, ornode.right.left == node
If we do not set
foundNode.left = null
, then the above invariant is not restored, and this could be an issue if there is still a reference tofoundNode
outside of the function's execution context.As to
foundNode.data = null
: that should not really be necessary. If the node referenced byfoundNode
is not referenced elsewhere, thenfoundNode
can be garbage collected. And if there is also no other reference to its data, then also that data can be garbage collected. Setting this property tonull
does not really change that process. Secondly, if we consider the case where there still might be a reference to this node, thennull
might be data that is actually meaningful in the overall algorithm, so setting it tonull
is not guaranteed to mark it in an unambiguous way as a "deleted" node.