以递归方式从链表中删除

时间:2017-10-27 00:20:31

标签: python recursion linked-list

我正在尝试将删除方法从有序链表转换为递归形式,但我遇到了麻烦。我正在尝试将remove_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

2 个答案:

答案 0 :(得分:1)

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

。下一个指针。

1

传统的迭代解决方案是使用while循环迭代列表,跟踪head V 0 --> 1 --> 2 -->(None) ^ ^ ^ prev cur next prev指针。 OPs发布的答案就是这样做的,而是使用递归调用代替while循环。

如果我们在迭代时使用递归堆栈来跟踪指针,则堆栈帧cur的当前指针是堆栈帧i的先前指针。如果我们i+1定义为一个函数,该函数在从列表中删除第一个数据实例后返回指向当前指向的列表或子列表的指针,那么我们可以执行指针更新当我们从堆栈中掉下来时。"

我们的递归定义如下:

  

基本情况

    1)从空列表中删除项目
       不能这样做。返回空列表(无)

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

  递归案例
     从下一个指针指向的子列表中删除该项。这是传递给remove_recursive(current, data)的{​​{1}}的定义。将remove_recursive设置为current.next的返回值并返回current.next

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

remove_recursive(current.next, data)

观察。这种递归方法在最坏的情况下使用O(N)内存,因为它使用堆栈来存储 all 之前的指针。迭代while循环方法仅使用O(1)额外内存,因为它只需要跟踪一个先前的指针。 OPs答案实际上是tail recursive,理论上会有O(1)记忆 - 除非我理解,python does not optimize for tail recursion

答案 1 :(得分:0)

这是我找到问题的解决方案

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