普通函数中为什么要返回一个头部,而在类函数中不返回?

huangapple go评论81阅读模式
英文:

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

huangapple
  • 本文由 发表于 2023年7月23日 18:30:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76747753.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定