Python 循环链表代码正在进入无限循环
我已经定义了循环链表,如下所示Python 循环链表代码正在进入无限循环,python,oop,linked-list,iterator,circular-list,Python,Oop,Linked List,Iterator,Circular List,我已经定义了循环链表,如下所示 class Link(object): def __init__ (self, data, next = None): self.data = data self.next = next class CircularList(object): def __init__ ( self ): self.first = Link(None, None) self.first.next
class Link(object):
def __init__ (self, data, next = None):
self.data = data
self.next = next
class CircularList(object):
def __init__ ( self ):
self.first = Link(None, None)
self.first.next = self.first
def insert_first ( self, item ):
new_link = Link(item)
new_link.next = self.first
self.first = new_link
def __iter__(self):
current = self.first
first = current
while current.next != first:
yield current
current = current.next
def __str__(self):
return str([Link.data for Link in self])
def __repr__(self):
return self.__str__()
然后我把这个项目插入我的列表
a = CircularList()
a.insert_first(4)
a.insert_first(5)
我想要循环列表的字符串表示,但它看起来像是无限循环的
\uu iter\uuu()
。我可以正确定义迭代器并获得正确的字符串表示形式吗?我将分解这些步骤
首先,我将链接
重命名为节点
class Node(object):
def __init__(self, data, next=None):
self.data = data
self.next = next
链接与节点不同——节点保存数据,链接将两个节点连接在一起
接下来,CircularList
类需要一些更改
\uuuu init\uuuu
将需要初始化一个空列表。这意味着根本没有节点。为了方便起见,我定义了self.last
,以大大简化代码(请注意,如果不这样做,您的工作会很困难)
对于insert_first
,当列表为空时,您需要处理一个角案例,以及一般案例。相应地更新self.first
和self.last
def insert_first(self, item):
if self.first is None:
self.first = self.last = Node(item)
self.first.next = self.first
else:
self.first = Node(item, self.first)
self.last.next = self.first
您的\uuu iter\uuu
方法也应该以实物形式响应。内联评论
def __iter__(self):
# corner case - yield empty list
if not self.first:
yield []
else:
# start by yielding the head node
yield self.first
cur = self.first.next
# iterate as long as you do not see the head node again
while cur is not self.first:
yield cur
cur = cur.next
其他方法保持不变。测试代码:
a = CircularList()
for i in [5, 4, 3, 2, 1]:
a.insert_first(i)
print(a)
[1, 2, 3, 4, 5]
完整代码列表
class Node(object):
def __init__(self, data, next=None):
self.data = data
self.next = next
class CircularList(object):
def __init__(self):
self.first = self.last = None
def insert_first(self, item):
if self.first is None:
self.first = self.last = Node(item)
self.first.next = self.first
else:
self.first = Node(item, self.first)
self.last.next = self.first
def __iter__(self):
if not self.first:
yield []
else:
yield self.first
cur = self.first.next
while cur is not self.first:
yield cur
cur = cur.next
def __str__(self):
return str([Link.data for Link in self])
def __repr__(self):
return self.__str__()
如果在
\uuu iter\uuuu
中用first=self.first
替换first=current
是否有效?@ndmeiri否,它不起作用您的insert\u first
方法不正确-您没有正确更新指针。我建议你拿几个例子,在纸上追踪它们,并确认它确实不起作用。@juanpa.arrivillaga对不起,我对面向对象编程很陌生,不明白你在说什么……你是best@EricKim我希望这个答案教会了你一些东西。祝你好运嘿,你的代码工作得很好,但是对于insert_first(),如果我把self.first=Link(item),self.last=Link(item),由于某种原因它就不工作了。(它似乎无限重复)。你在一行中做了self.first=self.last=Link(项目),但我试着在两行中做,然后它就不起作用了。你知道为什么吗?@EricKim这里的诀窍是self.first和self.last需要指向完全相同的对象,否则代码在cur上失败。first
,因为is
检查对象的身份(又名id
,它们与你的更改不一样)。哦,这很有意义。非常感谢。
class Node(object):
def __init__(self, data, next=None):
self.data = data
self.next = next
class CircularList(object):
def __init__(self):
self.first = self.last = None
def insert_first(self, item):
if self.first is None:
self.first = self.last = Node(item)
self.first.next = self.first
else:
self.first = Node(item, self.first)
self.last.next = self.first
def __iter__(self):
if not self.first:
yield []
else:
yield self.first
cur = self.first.next
while cur is not self.first:
yield cur
cur = cur.next
def __str__(self):
return str([Link.data for Link in self])
def __repr__(self):
return self.__str__()