Python单链接列表与尾巴

时间:2015-02-09 01:15:36

标签: python

我有一个链表,我希望将其作为队列实现。我已经发现它有效但我对这个特定部分的工作原理有疑问。这是代码:

class LinkedQueue:
    class _Node:
        def __init__(self, element, next):
            self._element = element
            self._next = next

    def __init__(self):
        self._head = None
        self._tail = None
        self._size = 0

    def enqueue(self, e):
        newest = self._Node(e, None)
        if self.is_empty():
            self._head = newest
        else:
            self._tail._next = newest
        self._tail = newest
        self._size += 1

如果队列为空并且我入队,则入队中的第一个条件为真并且被触发并且最新被分配给self._head。但是,当我添加另一个元素时,会触发else块,并且最新分配self._tail._next。显然,这会改变_head的_next变量。但是,在分配第三个元素时,_head的_next变量不会更改。为什么会这样?另外,最近不应该_tail改变,因此_next变量被新分配的None覆盖?

代码完全有效,我理解链接列表逻辑,但我不明白为什么这个特定代码有效。

2 个答案:

答案 0 :(得分:1)

你问:

  

self._tail._next已分配newest。显然,这改变了   _next的{​​{1}}变量。

是的,因为当时_head_tail是同一对象的两个名称。

当然,分配给_head与分配给_tail._next会产生完全相同的效果 - 怎么可能不会,因为_head._next_tail指的是非常相同的对象?

让我们看看它们是如何引用同一个对象的!当_head分支执行时,您执行if;然后在self._head = newest if/else之后无条件地执行。在Python中,赋值总是通过引用 - 赋值(对于名称[*])本身永远不会隐式地复制。

(将分配给一个列表是一个非常不同的操作,从而这个迂腐的括号 - 但是现在让我们忘记它,因为你没有处理对切​​片的赋值: - )。

  

但是,在分配第三个元素时,self._tail = newest变量为_next   没有改变。为什么会这样?

因为在那个时候_head_tail是同一个对象的两个名称并不是真的:它们就是不同对象的名称。

那是因为第二次你已经分配了不同的东西(_head)到newest - 但是没有给self._tail分配任何新东西,因此仍然指的是上一个对象... self._head不再提及。

  

此外,_tail不应更改_tail,因此newest   变量被新分配的无?

覆盖

_next确实被重新约束("更改"是一个非常含糊的术语! - )来引用与self._tail相同的对象,所以如果你打印{{1}那时(在newest方法的最后),您确实会将其视为self._tail._next。但是,之前的enqueue分配会影响当时提到的None的{​​{1}}属性 之前 { {1}}!) - 具有self._tail._next新分配的节点立即成为列表中的倒数第二个节点。

答案 1 :(得分:0)