Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 循环链表代码正在进入无限循环_Python_Oop_Linked List_Iterator_Circular List - Fatal编程技术网

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__()