Let's think about what you need to do. You have a pointer to a new node el
and you want to make that node the new first node in your list. You have the address of the first node. To make el
your new first node, you need to have el->next
point to the first node, and then replace the node at the address of the first node with el
. This method is called forward-chaining. (ironically, forward-chaining results in a list that is in the reverse order from how the nodes were added)
A trivial implementation would be:
void insertFirst(struct DLinkedList **first, struct DLinkedList *el)
{
if (*first != NULL) { /* if list not-empty */
el->next = *first; /* set el->next to head node */
*first = el; /* replace node at address of *first with el */
}
But, what happens if the list is currently empty? If you are adding el
as the first node, you must ensure the el->next
pointer is initialized NULL
. (which is may be in the function that creates the node, but that isn't shown). To handle that case to ensure the list is valid, you would add:
void insertFirst(struct DLinkedList **first, struct DLinkedList *el)
{
if (*first != NULL) /* if list not-empty */
el->next = *first; /* set el->next to head node */
else /* list empty */
el->next = NULL; /* set el->next to NULL */
*first = el; /* replace node at address of *first with el */
}
At this point we have validated whether the list is empty or not, and we have ensured that the el->next
pointer is NULL
if el
is added as the first node in an empty-list, but what if el
itself is NULL
when your function is called?
You can protect against that case, fully validating all parameters in your function as follows:
void insertFirst(struct DLinkedList **first, struct DLinkedList *el)
{
if (el == NULL) /* validate el not NULL, if so return */
return;
if (*first != NULL) /* if list not-empty */
el->next = *first; /* set el->next to head node */
else /* list empty */
el->next = NULL; /* set el->next to NULL */
*first = el; /* replace node at address of *first with el */
}
The level of validation needed above will depend on the remainder of your code not shown in your question. When in doubt, the last version will cover all bases. The only case not covered above is the case where *first
is uninitialized and *el == NULL
-- that case is left to you as an exercise. (but handling the case where*first
is indeterminate isn't something that can be done in your insertFirst()
function)
Now, after going though each of the considerations surround whether the list is empty or you are adding to an existing list, and in checking whether the el
parameter is not NULL
, your insertFirst()
function boils down to the following -- where the forward-chaining operation is the same, regardless of the state of the list when insertFirst()
is called:
void insertFirst(struct DLinkedList **first, struct DLinkedList *el)
{
if (el == NULL) /* validate el not NULL, if so return */
return;
el->next = *first; /* set el->next to head node */
*first = el; /* replace node at address of *first with el */
}
(so long as your list is initialized properly)
Look things over and let me know if you have further questions.