【问题标题】:Combining linked lists iteratively迭代组合链表
【发布时间】:2016-06-20 11:30:19
【问题描述】:

我正在尝试迭代地组合两个链表,但我现在所拥有的结果却相反。如果在创建结果列表之后,有没有办法以正确的顺序组合列表而不必反转?

class Link: 
    empty = ()

    def __init__(self, first, rest=empty):
        assert rest is Link.empty or isinstance(rest, Link)
        self.first = first
        self.rest = rest

    def __add__(self, lst):
        """ 
        >>>s = Link(1, Link(2))
        >>>s + Link(3,Link(4))
        Link(1,Link(2,Link(3,Link(4))))
        """
        result = Link.empty 
        while self is not Link.empty: 
            result = Link(self.first,result)
            self = self.rest 

        while lst is not Link.empty: 
            result = Link(lst.first, result)
            lst = lst.rest 
        return result 

【问题讨论】:

  • 看起来你已经创建了一个堆栈。 :)
  • 您的列表是否旨在不可变?这很重要,因为不可变列表允许您采取一些捷径(例如重用列表的一部分),如果列表可能被其他代码修改,您就无法做到)。

标签: python linked-list iteration


【解决方案1】:

从概念上讲,要合并两个链表,只需找到第一个链表的tail,并将其与第二个链表的head连接,然后返回第一个列表的头部。当前代码的主要问题是您没有保持在第一个列表的头部。

我假设您希望 __add__ 方法创建一个由 self 后跟 lst 组成的副本,因此只需先从 self 创建 Links 的副本,然后再创建 @987654326 @ 并在您迭代时附加它们。像这样:

def __add__(self, lst):
    result = Link(self.first)
    cur = result
    self = self.rest
    # Copy our list
    while self is not Link.empty:
        cur.rest = Link(self.first)
        cur = cur.rest
        self = self.rest
    # Copy and connect the Links in lst
    while lst is not Link.empty:
        cur.rest = Link(lst.first)
        cur = cur.rest
        lst = lst.rest
    return result

要诊断当前代码的问题,请考虑通过示例逐步完成。假设selfLink(1,Link(2))

    result = Link.empty 
    while self is not Link.empty: 
        result = Link(self.first,result)

result 现在是什么?

  • Link(self.first,result)
  • Link(1, Link.empty)

        self = self.rest
    

现在selfLink(2,())

        result = Link(self.first,result)

result 现在是什么?

  • Link(self.first,result)
  • Link(2, Link(1, Link.empty))

哎呀。发现问题;您正在反向连接链接。

【讨论】:

    【解决方案2】:

    避免更改self,找到第一个列表的末尾,并将第二个列表添加到其中。

    def __add__(self, lst):
        current = self
    
        while current.rest != self.empty:
            current = current.rest
    
        current.rest = lst
    
        return self
    

    或者,如果您希望返回一个新的链表:

    def __add__(self, lst):
        new_list = Link(self.first)
        new_link = new_list
    
        current = self
    
        while current.rest != self.empty:
            new_link.rest = Link(current.first)
            new_link = new_link.rest
    
            current = current.rest
    
        current = lst
    
        while current != self.empty:
            new_link.rest = Link(current.first)
            new_link = new_link.rest
    
            current = current.rest
    
        return new_list
    

    注意:这将引用每个 Link.first 值(不是独立副本)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-06
      • 2016-03-02
      • 2016-01-09
      • 2018-10-06
      • 2016-07-08
      • 1970-01-01
      相关资源
      最近更新 更多