迭代链表的函数

时间:2016-11-13 04:09:10

标签: python linked-list

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

def list_to_ll(l):
    if l == []:
        return None
    front = rear = LN(l[0])
    for v in l[1:]:
        rear.next = LN(v)
        rear = rear.next
    return front

def add_after(ll,value,new):
    for item in ll:
        if item == value:
            ll.insert(ll.index(value),new)

我正在研究一个名为add_after的迭代函数。它需要链表和两个值,值和新值。它改变了链表,使得每次出现的值现在都跟随new。例如:

a = list_to_ll([2,1,8,2,2,4,2,5,2])

add_after(a,2,-1)导致引用包含值1-> 8-> 2-> -1-> 4-> 2-> -1的链表。 - > 5→2→-1->无

add_after(a,2,2)用于原始列表中的结果,其引用包含值1-> 8-> 2-> 2-> 4-> 2-的链表。 > 2→5→2→2→。无

plus(我的代码中不允许使用列表,元组,集合或词组)

仅使用链接列表处理

当我运行add_after时,它会给我一个错误:

add_after(ll,2,-1)
for item in ll:
TypeError: 'LN' object is not iterable

任何人都可以帮我修复add_after功能吗?非常感谢。

3 个答案:

答案 0 :(得分:2)

  1. 通过定义产生节点的LN方法,使__iter__可迭代:
  2. add_after链接新节点。
  3. class LN:
        def __init__(self, value, next=None):
            self.value = value
            self.next  = next
    
        def __iter__(self):  # yield all linked node (including the first node)
            node = self
            while node is not None:
                yield node
                node = node.next
    
    def list_to_ll(l):
        if l == []:
            return None
        front = rear = LN(l[0])
        for v in l[1:]:
            rear.next = LN(v)
            rear = rear.next
        return front
    
    def add_after(ll, value, new):
        for item in ll:
            if item.value == value:
                ll.next = LN(new, ll.next)  # Make new node and link after current node
                break
        # TODO: Handle not-found case.
    
    
    ll = list_to_ll([2,1,8,2,2,4,2,5,2])
    add_after(ll, 2, -1)
    for item in ll:
        print(item.value)
    
    # Prints 2, -1, 1, 8, 2, 2, 4, 2, 5, 2
    
    阅读OP的评论后,

    更新 =>仅更改add_after(手动循环遍历节点):

    def add_after(ll, value, new):
        node = ll
        while node is not None:
            if node.value == value:
                node.next = LN(new, node.next)
                break
            node = node.next
    

    注意:我使add_after只添加一个节点。我将把它作为你添加多个节点的工作。

答案 1 :(得分:0)

ll是用户定义的类LN的对象。它不像列表那样可迭代,因此for-each构造在这种情况下不起作用。

以下是替代方案。

def add_after(ll,value,new):
    item = ll
    while item is not None:
        if item.value == value:
            newnode = LN(new, item.next)
            item.next = newnode
            break
        else:
            item = item.next

解决OP在第 n 次插入时的问题,以下代码也适用:

def add_after(ll,value,new,occ=1):
    item = ll
    while item is not None:
        if item.value == value:
            occ -= 1
            if occ == 0:
                newnode = LN(new, item.next)
                item.next = newnode
                break
        item = item.next

可选的第四个参数确定应在何时插入新值。例如,add_after(ll, 2, -1, 2)在第二次出现2后添加-1。

答案 2 :(得分:0)

这是我使用递归的解决方案。我还添加了一个辅助方法flatten来可视化我测试时的更改。

def add_after(ll, at_value, new_value):
    if ll.value == at_value:
        ll.next = LN(new_value, ll.next)
        if ll.next is not None and ll.next.next is not None:
            # skips over the newly added LN
            add_after(ll.next.next, at_value, new_value)
    elif ll.next is not None:
        add_after(ll.next, at_value, new_value)

def flatten(ll):
    if ll.next is None:
        return [ll.value]
    return [ll.value] + flatten(ll.next)

# Output
>>> a = list_to_ll([2,1,8,2,2,4,2,5,2])
>>> flatten(a)
[2, 1, 8, 2, 2, 4, 2, 5, 2]
>>> add_after(a, 2, -1)
>>> flatten(a)
[2, -1, 1, 8, 2, -1, 2, -1, 4, 2, -1, 5, 2, -1]
>>> b = list_to_ll([2,1,8,2,2,4,2,5,2])
>>> add_after(b, 2, 2)
>>> flatten(b)
[2, 2, 1, 8, 2, 2, 2, 2, 4, 2, 2, 5, 2, 2]