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
功能吗?非常感谢。
答案 0 :(得分:2)
LN
方法,使__iter__
可迭代:add_after
链接新节点。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]