【问题标题】:Recursive implementation of a singly linked list class in pythonpython中单链表类的递归实现
【发布时间】:2015-05-06 12:10:55
【问题描述】:

前段时间我决定学习算法,但自学并不是一件容易的事,所以我正在阅读 Goodrich 的一本书Python 中的数据结构和算法,但我'我坚持练习 C-7.27

给出一个单链表类的递归实现,这样一个非空列表的实例存储它的第一个元素和对剩余元素列表的引用。提示:将头节点之后的节点链视为自己形成另一个列表。

我之前使用函数进行了递归,但在类级别上对我来说有点抽象。 我有这个基础结构,但我不知道如何继续。

class SinglyLinkedList:
    '''A base class providing a single linked list representation'''

    class _Node:
        """non public class for storing a singly linked node"""
        __slots__ = '_element', '_next'  # streamline memory usage

        def __init__(self, element, next_el):
            self._element = element
            self._next = next_el

    def __init__(self):
        self._header = self._Node(None, None)
        self._header._next = self._header
        self._size = 0

    def __len__(self):
        return self._size

    def is_empty(self):
        return self._size == 0

据我了解,_Node._next 应该带有类似这样的 SinglyLinkedList 类:

def append(self, e):
    newest = _Node(e, SinglyLinkedList())

但是现在用递归来修饰它,这样我就可以将它作为一个整体来描绘。有谁能帮帮我吗?

【问题讨论】:

    标签: python algorithm class recursion


    【解决方案1】:

    首先:在单向链表中,最后一个节点不应该链接到任何东西;使用None 表示列表的结尾。在您的代码中,最后一个节点链接回自身。

    使用实例的递归只是意味着您仍然会调用相同的方法,但会在另一个实例上调用,而不是在 self 上使用全局函数或相同的方法。

    为了追加到一个链表,你会在下一个节点上调用append(),递归终止条件是处理在没有下一个节点的节点上追加(例如结束列表):

    class _Node:
        """non public class for storing a singly linked node"""
        __slots__ = '_element', '_next'  # streamline memory usage
    
        def __init__(self, element, next_el):
            self._element = element
            self._next = next_el
    
        def append(self, element):
            if self._next is not None:
                self._next.append(element)
            self._next = SinglyLinkedList._Node(element, None)
    

    您还需要向SinglyLinkedList 类添加一个append() 方法,以启动递归并调整长度。

    顺便说一句,您需要在SinglyLinkedList.__init__ 中以self._head = None 开头以获得一个空列表。追加时处理这种情况;空列表 -> 创建第一个节点,非空 -> 递归:

    def append(self, element):
        if self._head is None:
            self._head = self._Node(element, None)
        else:
            self._head.append(element)
        self._size += 1
    

    请注意,您不必在 SinglyLinkedList 类中“嵌套”_Node;它只会使您自己的代码更难引用该类。我不得不在_Node.append() 中使用SinglyLinkedList._Node() 来引用该类;另一种方法是使用type(self)()

    【讨论】:

    • 谢谢马丁。它现在有所帮助,我需要一些时间来掌握这个概念。欢呼