【问题标题】:How can I recursively add to a linked list in Python?如何递归地添加到 Python 中的链表?
【发布时间】:2020-09-08 13:57:33
【问题描述】:

我在对链表使用递归时遇到问题。 我希望能够将另一个节点添加到有序链表中。

我有这门课:

class Link:
    def __init__(self,value,next=None):
        self.value = value
        self.next  = next

下面是递归函数,到目前为止除了识别基本情况外,它并没有做太多事情

注意:它不是Link中的方法,它是一个单独的函数:

def add(ll, v):
    if ll == None:
        return Link(v)
    else:
         ll.next = add(ll.next,v)
         return ll

例子:我有这个链表A

1->3->8->12->None

我打电话给add(A, 10),它应该以正确的顺序添加 10。

1->3->8->10->12->None

我应该如何修改我的代码以使其正常工作?

【问题讨论】:

    标签: python recursion linked-list


    【解决方案1】:

    递归是一种函数式遗产,因此将其与函数式风格一起使用会产生最佳效果。我们先从最小的位开始 -

    # linked_list.py
    
    empty = None
    
    class node:
      def __init__(self, value, next = empty):
        self.value = value
        self.next = next
    
    def to_str(ll = empty):
      if not ll:
        return "None"
      else:
        return f"{ll.value}->{to_str(ll.next)}"
    
    # main.py
    
    from linked_list import node, to_str
    
    t = node(1, node(3, node(8, node(12))))
    print(to_str(t))
    # 1->3->8->12->None
    

    现在我们实现add -

    # linked_list.py
    empty = # ...
    
    class node: # ...
    
    def to_str(ll = empty): # ...
    
    def add(ll = empty, v = 0):
      if not ll:
        return node(v)
      elif ll.value >= v:
        return node(v, ll)
      else:
        return node(ll.value, add(ll.next, v))
    # main.py
    
    from linked_list import node, to_str, add
    
    t = node(1, node(3, node(8, node(12))))
    print(to_str(t))
    # 1->3->8->12->None
    
    t2 = add(t, 10)
    print(to_str(t2))
    # 1->3->8->10->12->None

    现在我们看看如何通过组合较小的位来制作更大的位。我们可以创建一个linked_list 类来捆绑它 -

    # linked_list.py
    
    empty = # ...
    
    class node: # ...
    
    def to_str(ll = empty): # ...
    
    def add(ll = empty, v = 0): # ...
    
    class linked_list:
      def __init__(self, root = empty):
        self.root = root
      def __str__(self):
        return to_str(self.root)
      def add(self, v):
        return linked_list(add(self.root, v))

    现在我们可以在面向对象的风格中使用linked_list,但仍然可以获得函数式风格的持久优势 -

    #main.py
    
    from linked_list import linked_list
    
    t = linked_list().add(1).add(3).add(8).add(12)
    print(t)
    # 1->3->8->12->None
    
    print(t.add(10))
    # 1->3->8->10->12->None
    
    print(t)
    # 1->3->8->12->None
    

    也许我们可以通过定义from_listto_list 来扩展我们的linked_list 模块-

    # linked_list.py
    
    empty = # ...
    
    class node: # ...
    
    def to_str(ll = empty): # ...
    
    def add(ll = empty, v = 0): # ...
    
    def from_list(l = []):
      if not l:
        return empty
      else:
        return node(l[0], from_list(l[1:]))
    
    def to_list(ll = empty):
      if not ll:
        return []
      else:
        return [ ll.value ] + to_list(ll.next)
    
    class linked_list:
      def __init__ # ...
      def __str__ # ...
      def add # ...
    
      def from_list(l):
        return linked_list(from_list(l))
    
      def to_list(self):
        return to_list(self.root)
    # main.py
    
    from linked_list import linked_list
    
    t = linked_list.from_list([ 1, 3, 8, 12 ])
    print(t)
    # 1->3->8->12->None
    
    print(t.add(10))
    # 1->3->8->10->12->None
    
    print(t.add(11).to_list())
    # [1, 3, 8, 11, 12]

    【讨论】:

      【解决方案2】:

      你需要一个额外的基本情况,当你找到一个不小于你想要按顺序插入的值时停止递归:

      elif v <= ll.value:
          return Link(v, ll)
      

      所以完整的代码可以是:

      class Link:
          def __init__(self,value,next=None):
              self.value = value
              self.next  = next
      
          def values(self):
              yield self.value
              if self.next:
                  yield from self.next.values()
      
      def add(ll, v):
          if ll is None:
              return Link(v)
          elif v <= ll.value:
              return Link(v, ll)
          else:
              ll.next = add(ll.next, v)
              return ll
      
      # example list
      A = Link(1, Link(3, Link(8, Link(12))))
      # add 10 to it:
      A = add(A, 10)
      # print list
      print(list(A.values()))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-13
        • 1970-01-01
        • 2020-01-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-15
        相关资源
        最近更新 更多