There is a double pointer in both. Look at these two analogous lines from the two functions:
*head=temp; // from insertAtTop
head->next=temp; // from insertAtLast
Note that head->next = temp
can be equivalently written as (*head).next = temp
.
There is a "double pointer" there: head
is a pointer to a structure, and that structure contains a pointer next
. Basically these two pictures:
Diagram for *head = temp
:
head --> [ *--]---> old_head
^
`-- temp is stored here, replacing the old_head
Diagram for head->next = temp
, or (*head).next = temp
. For the sake of example, the node structure is represented as three memory cells, the third of which is the next
field. The exact memory details depend on your compiler and how you defined the structure!
head --> [ ]
[ ]
[ *--]--> old_next
^
`-- temp is stored here, replacing old_next
Basically, the only difference is that you we have a structure instead of a just a single pointer object.
In both cases, a pointer is being updated to refer to the newly inserted node. In the insertAtTop
case, we have to replace that very pointer which represents the list itself. We are representing a list object as a pointer to the first node. If the list is changed so that it has a different first node, that pointer has to change. When inserting elsewhere in the list, we must update the previous node's next
pointer to point to the new node, so we assign to (*head).next
.
We could rewrite insertAtLast
to use insertAtTop
as a subroutine:
node* insertAtLast(node* head, int value){
/* find the insertion point */
node* original_head = head;
while(head->next!=NULL){
head=head->next;
}
/* now treat that as the head */
(void) insertAtTop(&head->next, value);
return original_head;
}
If you trace what happens in the call to insertAtHead
, you will find that it does exactly the same thing as the code which we replaced. We took out this code:
node* new_node=new node();
new_node->data=value;
new_node->next=NULL;
h->next=new_node;
But that's almost the same as the body of insertAtHead
which is this:
node* temp=new node();
temp->data=value;
temp->next=*head;
*head=temp;
We pass the value of the expression &h->next
as the head
parameter. So temp->next = *head
is really temp->next = *&h->next
where the *&
cancel out, leaving temp->next = h->next
. But we know that h->next
is NULL
: our while
loop has ensured that. So this is temp->next = NULL
, effectively.
And of course *head = temp
is the same as *(&h->next) = temp
, which is h->next = temp
.