英文:
Why do we return a head in normal function and don't return it in class function?
问题
好的,以下是翻译好的部分:
好的,我已经做了一段时间的链表,我遇到了一些问题,请考虑以下Python代码:
def EndInsertion(head,key):
curr = head
if head == None:
new_head = Node(key)
return new_head
else:
new_node = Node(key)
while curr.next != None:
curr = curr.next
curr.next = new_node
return head
def printList(head):
if head == None:
print(None)
curr = head
while curr != None:
print(curr.key, end = " ")
curr = curr.next
class Node:
def init(self,key):
self.key = key
self.next = None
head = None
printList(head)
head = EndInsertion(head,26)
head = EndInsertion(head,35)
head = EndInsertion(head,33)
printList(head)
我不太理解在这里返回链表的头部的原因,除非我们在链表中插入第一个节点?
现在看看这段代码:-
class Node:
def init(self,key):
self.key = key
self.next = None
class LinkedList:
def init(self):
self.head = None
def insert(self,key):
new_node = Node(key)
if self.head == None:
self.head = new_node
else:
curr = self.head
while curr.next != None:
curr = curr.next
curr.next = new_node
在这里,我们没有返回链表的头部?每次在其中插入元素时,我创建的链表如何知道头部已被更新?
英文:
Okay, So I have been doing linked lists for some time now and I have stumbled upon something, consider the following python code:
def EndInsertion(head,key):
curr = head
if head == None:
new_head = Node(key)
return new_head
else:
new_node = Node(key)
while curr.next != None:
curr = curr.next
curr.next = new_node
return head
def printList(head):
if head == None:
print(None)
curr = head
while curr != None:
print(curr.key, end = " ")
curr = curr.next
class Node:
def __init__(self,key):
self.key = key
self.next = None
head = None
printList(head)
head = EndInsertion(head,26)
head = EndInsertion(head,35)
head = EndInsertion(head,33)
printList(head)
I don't particularly understand the reason of returning the head of a Linked List here, except for when we are inserting the first node in the linked list ?
Now see this code:-
class Node:
def __init__(self,key):
self.key = key
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def insert(self,key):
new_node = Node(key)
if self.head == None:
self.head = new_node
else:
curr = self.head
while curr.next != None:
curr = curr.next
curr.next = new_node
Here, we do not return the head of the linked list ? how does the linked list I created know about the head being updated everytime I insert the element in it ?
答案1
得分: 2
你提供了采用不同方法的实现。第一个只定义了一个 Node
类,并由链表的用户自行管理他们自己的 head
引用。第二个实现将这个责任从用户手中拿走,并由容器类 LinkedList
进行管理。
现在回答你的问题:
> 我不特别理解在这里返回链表的头部的原因,除非我们在链表中插入第一个节点?
确实,只有在插入第一个节点时才需要它。但是如果主程序中的逻辑更加不可预测,比如当你有一个用户菜单,用户可以选择在链表中插入或删除元素。那么你就需要检查是否处于列表为空的特殊情况,以确保你使用返回值来赋值给 head
... 因此,总是赋值给 head
是有意义的,即使你知道如果列表不为空时实际上并不是必要的:它可以节省你做额外的空测试。
> 这里,我们没有返回链表的头部?
使用第二个实现时,链表的用户不应该被打扰到管理链表的头部。这现在由 LinkedList
类的逻辑来处理。
> 我创建的链表如何知道在每次插入元素时头部被更新了?
首先,它并不需要在每次都被更新。正如你正确地注意到的,这在第一个实现中也是如此。
在这个实现中(使用 LinkedList
的实现),选择的逻辑是进行检查以确定链表是否为空,只有在列表为空时才更新 self.head
属性。
它也可以被实现成在任何情况下都分配给 self.head
。但是重要的是要意识到,当列表不为空时,这个赋值不会改变任何东西,也就是说,在这种情况下,分配的引用与在赋值之前 self.head
已经存在的引用相同。
为了说明第二个实现也可以选择始终分配给 self.head
,我在这里提供了这样一个可替代的实现:
class LinkedList:
def __init__(self):
self.head = None
def insert(self, key):
head = self.head
if head is None:
head = Node(key)
else:
new_node = Node(key)
curr = head
while curr.next:
curr = curr.next
curr.next = new_node
self.head = head # 总是分配
英文:
You have presented implementations that take a different approach. The first one only defines a Node
class and leaves it to the user of the linked list to manage their own head
reference. The second implementation takes this responsibility out of the hands of the user and manages it with the container class LinkedList
.
Now to your questions:
> I don't particularly understand the reason of returning the head of a Linked List here, except for when we are inserting the first node in the linked list ?
Indeed, it is only needed for when inserting the first node. But what if the logic in the main program is much more unpredictable, for instance when you have a user menu where the user is allowed to choose to insert or delete an element from the linked list. Then you would need to check whether you are in the special case where the list is empty to make sure you use the return value to assign it to head
... So it makes sense to always assign to head
even when you know it wasn't really necessary if the list was not empty: it saves you from doing the extra empty-test.
> Here, we do not return the head of the linked list ?
With the second implementation, the user of the linked list is not supposed to be bothered with managing the head of the list. This is now done by the LinkedList
class logic.
> how does the linked list I created know about the head being updated every time I insert the element in it ?
First of all, it doesn't have to be updated every time. This is also true with the first implementation as you correctly noticed.
In this implementation (the one with LinkedList
), the chosen logic was to perform the check on whether the list is empty or not, and only update the self.head
attribute when the list is empty.
It could also have been implemented differently, where the assignment to self.head
always happens. But it is important to realise that this assignment changes nothing when the list was not empty, i.e. in that case the assigned reference is the same as what self.head
already was before the assignment.
Just to illustrate that the second implementation could also have chosen to always assign to self.head
, I provide here such an alternative implementation:
class LinkedList:
def __init__(self):
self.head = None
def insert(self, key):
head = self.head
if head is None:
head = Node(key)
else:
new_node = Node(key)
curr = head
while curr.next:
curr = curr.next
curr.next = new_node
self.head = head # Always assigned
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论