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;
}
CodePudding user response:
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 by foundNode
.
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
and right
to null
, the following invariant is maintained for every node
:
- Either
node.left == null
, or node.left.right == node
...and similarly:
- Either
node.right == null
, or node.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 to foundNode
outside of the function's execution context.
As to foundNode.data = null
: that should not really be necessary. If the node referenced by foundNode
is not referenced elsewhere, then foundNode
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 to null
does not really change that process. Secondly, if we consider the case where there still might be a reference to this node, then null
might be data that is actually meaningful in the overall algorithm, so setting it to null
is not guaranteed to mark it in an unambiguous way as a "deleted" node.
CodePudding user response:
To be entirely clear: new Node()
would initialize the node fields left
and right
with null
.
That remove
sets all fields of the removed foundNode
to null
is a misguided attempt to optimize garbage collection.
You do not create lingering objects (other removed nodes), no memory leak. As a garbage collector can deal with collections of unreachable objects.
Mind: for other languages this might not hold.