Python 递归地从链表中删除

Python 递归地从链表中删除,python,recursion,linked-list,Python,Recursion,Linked List,我正在尝试将有序链表中的删除方法转换为递归形式,但在这样做时遇到了问题。我试图将remove\u recursive中的代码转换为递归形式,并认为我只需要将while语句更改为if并在最后调用函数,但这不起作用 def remove(self, item): curr = self.__head prev = None self.remove_recursive(item, curr, prev) def remove_recursive(self, item, cur

我正在尝试将有序链表中的删除方法转换为递归形式,但在这样做时遇到了问题。我试图将
remove\u recursive
中的代码转换为递归形式,并认为我只需要将
while
语句更改为
if
并在最后调用函数,但这不起作用

def remove(self, item):
    curr = self.__head
    prev = None
    self.remove_recursive(item, curr, prev)

def remove_recursive(self, item, curr, prev):
    while curr != None and curr.get_data() != item:
        prev = curr
        curr = curr.get_next()
    if prev == None:
        self.__head = curr.get_next()
    else:
        prev.set_next(curr.get_next())
    self.__count -= 1
我试过了

def remove_recursive(self, item, curr, prev):
    if curr != None and curr.get_data() != item:
        prev = curr
        curr = curr.get_next()
        return self.remove_recursive(item, curr, prev)
    if prev == None:
        self.__head = curr.get_next()
    else:
        prev.set_next(curr.get_next())
    self.__count -= 1

这就是我找到的解决问题的办法

def remove_recursive(self, item, curr, prev):
    if curr != None and curr.get_data() != item:
        prev = curr
        curr = curr.get_next()
        return self.remove_recursive(item, curr, prev)
    if prev == None:
        self.__head = curr.get_next()
    else:
        prev.set_next(curr.get_next())
    self.__count -= 1

要从链表中删除节点
N
,必须通过指向序列中
N
的下一个节点,使上一个节点的下一个指针跳过
N
。例如,如果我们有下面的列表,并且我们想要删除项
1
,我们实际上需要将
0
next
指针的值设置为
1
的下一个指针

head
 V
 0 --> 1 --> 2 -->(None)
 ^     ^     ^ 
prev  cur   next
传统的迭代解决方案是使用while循环对列表进行迭代,跟踪
prev
cur
指针。OPs posted应答确实做到了这一点,但它使用递归调用代替while循环

相反,如果我们在迭代时使用递归堆栈跟踪指针,堆栈帧
i
的当前指针就是堆栈帧
i+1
的上一个指针。如果我们
remove\u recursive(current,data)
定义为一个函数,在从列表中删除第一个数据实例后返回指向current指向的列表或子列表的指针,那么我们就可以在“从堆栈上掉下来”时执行指针更新

我们的递归定义如下所示:

基本案例

1) 从空列表中删除项目
不行。返回空列表(无)

2) 从列表前面删除该项目
删除第一项的子列表就是下一个指针指向的子列表。返回下一个指针。(如果允许重复项,并且您希望删除所有重复项,则继续在此处递归--请参阅下一步)

递归大小写:
从下一个指针指向的子列表中删除该项。这是
remove\u recursive
current的定义。下一步
传递给它。将
current.next
设置为
remove\u recursive(current.next,data)
的返回值,并返回
current

这是我的代码——它是更传统形式的递归解决方案


观察。这种递归方法在最坏的情况下使用O(N)内存,因为它使用堆栈存储所有以前的指针。迭代while循环方法只使用O(1)个额外内存,因为它只需要跟踪上一个指针。OPs的答案实际上和理论上都是O(1)内存——除非我理解它,。

“我认为我只需要将while语句更改为if并在最后调用函数,但这不起作用”-什么不起作用?您没有告诉我们您尝试了什么。您需要递归函数在返回后返回指向列表头的指针。我给你一个提示。从
remove
remove\u recursive
的第一个调用应该是
self\uuuuu.head=remove\u recursive(self\uuuuuuu.head,item)
@MFisherKDX刚刚将其更新为我以前尝试过的版本,这次似乎有效,也许我做了一些不同的事情,无论如何感谢您的帮助@BadUserName——如果你不介意挑剔的挑战,你可以发布你的代码作为问题的答案,看看会发生什么。我将对此投票,因为它是有效的。您将迭代方法中的while循环替换为递归。请注意,您必须跟踪上一个指针。您可以通过使递归堆栈保持上一个指针来更优雅地实现这一点,稍后我将发布一个大多数人都熟悉的替代递归解决方案。
def remove_recursive(self, cur, data):
    if cur == None:
        return None
    elif cur.get_data() == data:
        return cur.get_next() # removes only the first instance of data
    else:
        cur.set_next(self.remove_recursive(cur.get_next(), data))
        return cur

def remove(self, data):
    self.__head = self.remove_recursive(self.__head, data)