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方法创建了所有其他链表方法,非常感谢您为我指路!很抱歉反应太晚!很高兴它成功了!如果你还没有看的话,请看一看。