Python 为链表类实现递归Add方法时出现问题

Python 为链表类实现递归Add方法时出现问题,python,python-3.x,recursion,linked-list,Python,Python 3.x,Recursion,Linked List,我需要递归地为链表类实现add方法。我无法让我的代码工作。这就是我到目前为止所做的: 类链接列表: 定义初始化(自): self.head=无 def add(自身、val、当前_节点=0): 如果当前_节点==0: 当前_节点=self.head 如果当前_节点为无: 当前节点=节点(val) 其他: 添加(self、val、当前_节点.next) 这个实现哪里出了问题?这是对递归的滥用。如果链表的长度大于调用堆栈的大小,则类会无故中断。与迭代实现相比,它的编写效率和直观性也更低 话虽如此,

我需要递归地为链表类实现
add
方法。我无法让我的代码工作。这就是我到目前为止所做的:

类链接列表:
定义初始化(自):
self.head=无
def add(自身、val、当前_节点=0):
如果当前_节点==0:
当前_节点=self.head
如果当前_节点为无:
当前节点=节点(val)
其他:
添加(self、val、当前_节点.next)

这个实现哪里出了问题?

这是对递归的滥用。如果链表的长度大于调用堆栈的大小,则类会无故中断。与迭代实现相比,它的编写效率和直观性也更低

话虽如此,教授们通常要求不适合递归的算法以递归方式实现。我将编写一个内部助手来处理实际的递归。这避免了尴尬的默认参数,该参数可能会混淆调用者,并使调用者能够破坏函数的约定

def add(self, val):
    def add_recursively(curr, prev):
        if curr:
            add_recursively(curr.next, curr)
        else:
            if prev:
                prev.next = Node(val)
            else:
                self.head = Node(val)

    add_recursively(self.head, None)
最初尝试的主要问题是:

if current_node is None:
    current_node = Node(val)
如果不引用链中的前一个节点,
current\u node
实际上不会使用上述操作附加到任何对象,因此它只是在函数返回时被垃圾收集

如果允许您使用迭代,这是一种更自然的方法:

def add(self, val):
    curr = self.head
    prev = None

    while curr:
        prev, curr = curr, curr.next

    if prev:
        prev.next = Node(val)
    else:
        self.head = Node(val)
下面是一个最小的完整用法示例:

class Node:
    def __init__(self, val, next_node=None):
        self.val = val
        self.next = next_node

    def __str__(self): 
        return str(self.val)

class LinkedList:
    def __init__(self):
        self.head = None

    def add(self, val):
        curr = self.head
        prev = None

        while curr:
            prev, curr = curr, curr.next

        if prev:
            prev.next = Node(val)
        else:
            self.head = Node(val)

    def __str__(self): 
        nodes = []
        curr = self.head

        while curr:
            nodes.append(curr.val)
            curr = curr.next

        return "[" + " -> ".join(nodes) + "]"

if __name__ == "__main__":
    llist = LinkedList()
    llist.add("bananas")
    llist.add("apples")
    llist.add("cranberries")
    print(llist) # => [bananas -> apples -> cranberries]

除此之外,考虑保留<代码>自身>尾部<代码>节点引用,用于<代码>链接目录> /代码>类。这将使add操作成为O(1)而不是O(n)。

非常感谢您的完整解释。我试着测试你的代码版本,它在大部分情况下都能正常工作。但是,当我试图打印以前为空的链表中新添加的节点的数据时,它会打印节点对象id而不是值。例如,以下内容打印节点对象的ID而不是节点对象的值:linkedlist1=LinkedList(),打印(linkedlist1.head.data)此处提供的小代码段不应该工作,因为
head
最初是
None
,但我在测试代码中打印数据时没有问题。我添加了一个使用示例——如果它对您不起作用,请告诉我。我的示例测试代码出错,让您的代码正常工作。我还根据您提供的add方法创建了所有其他链表方法,非常感谢您为我指路!很抱歉反应太晚!很高兴它成功了!如果你还没有看的话,请看一看。