I was working on this problem from HackerRank trying to insert an element at the tail of a linked list and I have to return the head of the node.
def insertNodeAtTail(head, data):
if head is None:
head = SinglyLinkedListNode(data)
return head
current_head = head
while current_head.next:
current_head = current_head.next
current_head.next = SinglyLinkedListNode(data)
return head
SinglyLinkedListNode is a class for creating nodes with 2 methods: data which gives value to the node, and next which allows us to move on to the next node.
The code above works but my understanding is, if we mess or tweak with current_head, the changes will appear on head too (because that's how assigning works in Python). But the code is working perfectly. If I use return current_head, the answer is wrong. I did something similar such as
a = [1,2,3,4,5,6]
b = a
for i in range(5):
b.append(i)
And both array a and array b are identical and prints [1,2,3,4,5,6,0,1,2,3,4]. I'd appreciate any help I can get please. This inconsistency is messing with my head because the idea for inserting at the end of the tail is clearly easy but I keep getting worried about having to return the head of the node (and I can't do that if I keep misunderstanding whether I am changing anything to the LL).
Thank you in advance!
I was working on this problem from HackerRank trying to insert an element at the tail of a linked list and I have to return the head of the node.
def insertNodeAtTail(head, data):
if head is None:
head = SinglyLinkedListNode(data)
return head
current_head = head
while current_head.next:
current_head = current_head.next
current_head.next = SinglyLinkedListNode(data)
return head
SinglyLinkedListNode is a class for creating nodes with 2 methods: data which gives value to the node, and next which allows us to move on to the next node.
The code above works but my understanding is, if we mess or tweak with current_head, the changes will appear on head too (because that's how assigning works in Python). But the code is working perfectly. If I use return current_head, the answer is wrong. I did something similar such as
a = [1,2,3,4,5,6]
b = a
for i in range(5):
b.append(i)
And both array a and array b are identical and prints [1,2,3,4,5,6,0,1,2,3,4]. I'd appreciate any help I can get please. This inconsistency is messing with my head because the idea for inserting at the end of the tail is clearly easy but I keep getting worried about having to return the head of the node (and I can't do that if I keep misunderstanding whether I am changing anything to the LL).
Thank you in advance!
Share Improve this question asked Mar 26 at 22:34 gradstudent1995gradstudent1995 1051 silver badge 1 |2 Answers
Reset to default 2current_head
only points to head if it is the only node in the list, and yes, modifying it at that point would appear when viewing head
, but current_head
moves to locate the last node in the list.
Example:
After current_head = head
, both names refer to the same object:
+------+
| data |<---- head <---- current_head
| next |--\
+------+ |
|
+------+ |
| data |<-/
| next |----> None
+------+
After while current_head.next: current_head = current_head.next
, current_head
is re-assigned to point to the object that current_head.next
refers to, and that continues as long as current_head.next
doesn't refer to None
:
+------+
| data |<---- head
| next |--\
+------+ |
|
+------+ |
| data |<-/ <---- current_head
| next |----> None
+------+
Now current_head
refers to the last node in the list, no matter how many nodes were in the list.
After current_head.next = SinglyLinkedListNode(data)
, the last node is modified to refer to a new object:
+------+
| data |<---- head
| next |--\
+------+ |
|
+------+ |
| data |<-/ <---- current_head
| next |--\
+------+ |
|
+------+ |
| data |<-/
| next |----> None
+------+
If you return current_head
at this point, it would lose the first node. return head
is correct because it still points to the first node in the list.
A better name would be current_node
instead of current_head
.
The difference between the two scenarios is that in the first you have a loop that assigns something different to current_head
in each iteration, while in the second scenario you don't -- b
doesn't get assigned(!) something different.
We could alter the second scenario by actually doing an assignment to b
. To achieve that, we could make the list a nested list:
a = [None]
b = a
for i in range(5):
b[0] = [None]
b = b[0]
print(a)
print(b)
Now we have an assignment to b
, which gives us a more consistent comparison with the first scenario (of the linked list). And now we see that a
and b
are different, as the output produced is:
[[[[[[None]]]]]]
[None]
So a
references the whole structure that was created, while b
only references the last entry that was created inside it. This is quite similar how in the first scenario head
references the whole structure that was created and current_head
(despite its name), right after the loop, references the last node that was created before adding another one.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744122703a4559474.html
b = a
does not make a copy ofa
. It's just another reference to the same list. See nedbatchelder/text/names.html. – chepner Commented Mar 26 at 23:03