I was browsing the .NET Reference to see the internal workings of a LinkedList<T> and its corresponding LinkedListNode<T> elements when I noticed that I didn't quite understand how the AddLast(T item) and AddLast(LinkedListNode<T> node) methods worked. I will consider AddLast(T item) to address my confusion.
The way I see it, the method first creates a new node that refers to the current list and holds the required value to be added. Then it checks if the list is empty by looking at head, the supposed first item ever added to the list.
head is null
Calls a method called InternalInsertNodeToEmptyList(LinkedListNode<T> newNode) where newNode in this case will be result from the scope surrounding this method. It checks if the list is actually empty and then modifies the node to be added to link to itself in both directions, before setting it as the head of the list. Also updates the count and the version of the list.
private void InternalInsertNodeToEmptyList(LinkedListNode<T> newNode)
{
Debug.Assert( head == null && count == 0, "LinkedList must be empty when this method is called!");
newNode.next = newNode; // i.e. result.next = result
newNode.prev = newNode; // i.e. result.prev = result
head = newNode; // i.e. head = result
version++;
count++;
}
B) head is NOT null
Calls a method called InternalInsertNodeBefore(LinkedListNode<T> node, LinkedListNode<T> newNode) where node is head and newNode is result from the scope surrounding this method. First it checks if the list isn't empty, but then the actual logic of adding the new node follows:
private void InternalInsertNodeBefore(LinkedListNode<T> node, LinkedListNode<T> newNode)
{
newNode.next = node; // result.next = head
newNode.prev = node.prev; // result.prev = head.prev (but isn't head.prev just head?)
node.prev.next = newNode; // head.prev.next = result (so result gets added after head?)
node.prev = newNode; // head.prev = result (why does head link back to result?)
version++;
count++;
}
I really don't understand how this results in inserting a new link after the last known link of the list. Why does this not result in adding a link after head rather than after the last known link?