Python 3 - 在链表中使用递归

Posted

技术标签:

【中文标题】Python 3 - 在链表中使用递归【英文标题】:Python 3 - Using recursion in a linked list 【发布时间】:2021-12-22 18:37:33 【问题描述】:

Python 3 - 我是编码新手,发现递归很困难。我正在使用递归方法创建一个链表类,用于从列表中添加和删除项目。现在,如果某个项目恰好是我列表中的第一项,我将无法删除它。我编写了一些替代代码,如果我包含另一个参数(以前的)和另一个基本情况,则可以从列表中删除第一项,但是我可以 only 删除第一项并且花了太长时间试图找出原因,所以我完全放弃了。我将不胜感激!

另外,我已经知道我有 getter 并且没有正确使用它们。

class Node:
    """
    Represents a node in a linked list
    """
    def __init__(self, data):
        self._data = data
        self._next = None

    def get_data(self):
        """getter method for data in Node class"""
        return self._data

    def get_next(self):
        """getter method for next in Node class"""
        return self._next
class LinkedList:
    """
    A linked list implementation of the List ADT
    """
    def __init__(self):
        self._head = None

    def get_head(self):
        """getter function for head of list"""
        return self._head

    def add(self, val):
        """ Adds a node containing val to the linked list - helper function"""
        self._head = self.recursive_add(self._head, val)

    def recursive_add(self, node1, val):
        """ Adds a node containing val to the linked list """
        if node1 is None:
            return Node(val)
        else:
            node1._next = self.recursive_add(node1._next, val)
            return node1

    def remove(self, val):
        """removed the node containing val from the linked list - helper function"""
        self.recursive_remove(self._head, val)

    def recursive_remove(self, node1, val):
        """
        Removes the node containing val from the linked list
        """
        if node1 is None:
            return node1
        elif node1._data == val:
            return node1._next
        else:
            node1._next = self.recursive_remove(node1._next, val)
            return node1

    def main():
       my_list = LinkedList()
       my_list.add(13)
       my_list.add(9)
       my_list.add(5)
       my_list.remove(9)
    


if __name__ == '__main__':
    main()

【问题讨论】:

如果您使用递归,您的代码将无法处理 CPython 中超过 1000 个元素的列表。最好使用循环,尽管我认为这纯粹是出于教学目的。不能给self.recursive_remove(self._head, val)的负责人分配任务吗? 哈哈现在我猜有一个课程使用相同的链表类:***.com/questions/69908090/… 要删除给定节点,只需说node.next = node.next.next。或者如果你想删除第一个节点,你可以说node = node.next 【参考方案1】:
    def remove(self, val):
        """removed the node containing val from the linked list - helper function"""
        if self._head and self._head._data == val:
            self._head = self._head._next
            return
        self.recursive_remove(self._head, val)

如果是开头,则需要更换头部。

【讨论】:

【参考方案2】:

remove 中调用recursive_remove,但忽略它的返回值。您应该将其用作(可能不同的)_head 引用,必须在递归方法本身中完成,您可以:

node1._next = self.recursive_remove(node1._next, val)
#       ^                                   │
#       └───────────────────────────────────┘

注意node1._next 是如何作为参数传递的,方法的返回值是node1._next 最终应该得到的(可能不同的)引用。 same 模式应该应用在remove 的初始调用中:

def remove(self, val):
    self._head = self.recursive_remove(self._head, val)
#          ^                                  │
#          └──────────────────────────────────┘

注意:add 中使用了相同的模式,您可以正确使用。

【讨论】:

以上是关于Python 3 - 在链表中使用递归的主要内容,如果未能解决你的问题,请参考以下文章

在链表中添加节点时使用双指针的原因是啥?

在链表中移动值之后。更改头部中的值会同时更改 2 个节点

为啥在链表中查找循环时将指针增加 2,为啥不增加 3、4、5?

关于在链表中使用时取消引用指针

链表----在链表中添加元素详解--使用链表的虚拟头结点

使用java在链表中插入节点