Reputation: 327
This is somewhat mind-boggling
i will try to explain my doubt.
Check this function for example:
void snoc(Lint *l, int val){
Lint i, new;
new = (Lint) malloc(sizeof(Nodo));
new->value = val;
new->next = NULL;
i=(*l);
while(i->next!=NULL){
i=i->next;
}
i->next = new;
}
I understand the concept behind and i have no trouble working with lists, taking in consideration that i can't iterate through the list using the list initial pointer itself (if i do this, i would lose the initial pointer right)
The thing is, making i=(*l)
and afterwards iterating through the list using i=i->next, is making the i variable becoming in constant change.
In this particular example, the original list will not change until i find the end of the linked list, and then i make an attribution and voilá! I insert an element at the end.
My doubt is, if by changing the i
, and making i->next = new
at the end, wouldn't that mean that everytime i make i=i->next
, change ALL the nodes in the original list?
Another example would be init:
void init (Lint *l){
Lint i, prev;
i=(*l);
prev=NULL;
while(i!=NULL){
if( (i->next)->next==NULL){
i->next = NULL;
}
i=i->next;
}
}
if i do this, the last element will be removed, by changing the i->next
to NULL, at the right moment. But before that, i've been making changes to the i
itself again, by telling i=i->next
If i were to make this change to the (*l)
itself (by doing (*l)=(*l)->next
) i would be ruining the original list .
I really hope you guys can understand my doubt.
Upvotes: 0
Views: 176
Reputation: 649
with some minors modifications your code is like this
void snoc(Lint *l, int val)
{
Lint i, new;
new = (Lint) malloc(sizeof(Nodo));
new->value = val;
new->next = NULL;
i = *l;
if(!(*l))
{
*l = new;
return;
}
while(i->next) i = i->next; // (1)
i->next = new; // (2)
}
and, this is its explanation:
In (1) we walk throught the linked list until its end. We know we are at the end because i->next
(which point after each loop step to the next nodo item) is null so in that case, we make i->next
point to the newly created nodo item in (2). But l
never changed during the function, l
is always pointing to the begining of our linked list so the purpose of this function is to add a new element at the end without changing the value of l
.
but also we can initialize our linked list with this function...for example:
Lint l = NULL;
snoc(&l, 10); // l will be initialized with a new nodo item with 10 as the value its value member
(0) checks if l
is null in that case we make *l
point to the newly allocated nodo item and return...so initialization done.
I add another way for the code above
void snoc(Lint *l, int val)
{
Lint now, new, previous;
new = (Lint) malloc(sizeof(Nodo));
new->value = val;
new->next = NULL;
if(!(*l)) // (0)
{
*l = new;
return;
}
for(now = *l; now; now = now->next)previous = now;
previous->next = new;
}
Upvotes: 1
Reputation: 84551
Yes, we do understand your confusion, and it comes from not working out the list pointers on a piece of paper so you can visualize what is taking place. Always use a diagram when you are working node
link issues. For example in your case with your singly linked-list, current node called i
(dubious choice of name) and your new node called new
a helpful diagram would be:
Singly Linked-List (non-circular)
Tail Current Head
(list start) i new
+------------+ +------------+ +------------+
| Payload | | Payload | | Payload |
+------------+ +------------+ +------------+
| Next |------->| Next |------->| Next |--->NULL
+------------+ +------------+ +------------+
Now, I bet you can tell what:
changing
i
, and makingi->next = new
at the end
would do. This isn't a dig or meant to be condescending, it is really the way you need to work out linked-list issues until you have done it enough you can visualize the pointer wiring in your head. This is even more important when you get to circular or doubly-linked list insertions and deletions. No matter what the problem, if you just write it down and label all the connections that are being made or broken, you can then code it cleanly in your editor.
Upvotes: 2
Reputation: 32640
I am not sure I understand your question, but why don't you simply copy the pointer? You can keep a pointer to the initial element and use a second one to traverse though it.
Upvotes: 0