0

我是一名 C++ 程序员。最近开始使用 Python。我正在查看 Python 中的简单链表实现。我在这里有点困惑。不仅在这里,而且在 Tree 实现等中也存在同样的问题。

class Element 包含数据和指向下一个节点的指针。完美没问题。但是在 LinkedList 类中我可以看到 self.tail.next=e,现在 next 是 Element 类的变量,即使它是公共的,但 Element 类的对象也必须访问它。在这里,我们如何编写 self.tail.next = e 之类的东西,因为 tail 只是 LinkedList 类的变量,而不是 Element 类的对象。我很困惑。

class Element:
        def __init__(self,x):
                self.data=x
                self.next=None


class LinkedList:
        def __init__(self):
                self.head=None
                self.tail=None

        def append(self,x):
                # create a new Element
                e = Element(x)
                # special case: list is empty
                if self.head==None:
                        self.head=e
                        self.tail=e
                else:
                        # keep head the same
                        self.tail.next=e
                        self.tail=e
4

5 回答 5

4

Python 使用引用。一切总是通过引用传递,值总是通过引用共享(除非明确复制)。

分配对象意味着将引用分配给该对象。这种方式self.tail.next = e意味着: self.tail 期望引用 Element 类的对象。该对象具有 .next 属性。这self.tail.next = e意味着非空列表的最后一个元素将指向刚刚附加的新元素。然后self.tail = e意味着对最后一个元素的引用被移动到刚刚附加的最后一个元素。

Python 中的任何变量都只是具有给定名称的引用变量。它会自动取消引用。因此,对于那些熟悉经典编译语言(如 C++)的人来说,它可能看起来很奇怪。

我不确定您是否可以在不创建帐户的情况下在 Expert Exchange 上显示文章。如果是,请查看http://www.experts-exchange.com/Programming/Languages/Scripting/Python/A_6589-Python-basics-illustrated-part-2.htmlhttp://www.experts -exchange.com/Programming/Languages/Scripting/Python/A_7109-Python-basics-illustrated-part-3.html用于解释问题的图像。

于 2012-04-23T10:50:59.370 回答
1

唯一初始化 self.tail 的地方是 append ,在那里你将它设置为等于 e。就在你上面一点点e = Element(x),所以 e一个 Element 类型的对象。请注意,在您打电话的那一刻,self.tail.next=e您知道 head 不是 none,因此 tail 也不是 None,而是 Element 的一个实例。

希望这可以帮助。

于 2012-04-23T10:37:25.643 回答
1

你写了:

现在 next 是 Element 类的变量,即使它是公共的,但 Element 类的对象也必须访问它。

那里有一个误解。公共成员(即除了以下划线开头的所有成员之外的所有成员)可以从任何地方访问,而不仅仅是从同一类的方法中访问。

于 2012-04-23T10:37:52.563 回答
0

next并且tail 元素,这就是原因。这适用于任何语言的链表,包括 C 或 C++。 链表是与指针/引用链接在一起的元素列表。

遍历列表时,这些链接用于从节点(元素)到节点。如果他们引用其他链表就没有意义了,不是吗?列表中的head第一个元素是 ,最后一个元素是tailnext节点中指向的元素是列表中它之后的元素,previous节点是它之前的元素。

于 2012-04-23T10:29:44.257 回答
0

在 python 中,一切都是参考。

请:将列表实现与您的(应用程序)数据分开。

与在 C++ 中一样,封装访问方法是一种很好的风格——尽管如此,因为对实例字段没有访问限制,所以可以从任何地方访问它们。

一个通用双链表的想法(这只是一个应该增强的骨架 - 但我希望它能够传达这个想法)。

class DoubleLinkedList(object):

    class ListNode(object):

        def __init__(self):
            self.__next = None
            self.__prev = None

        def next(self):
            return self.__next

        def prev(self):
            return self.__prev

        def set_next(self, next_node):
            self.__next = next_node

        def set_prev(self, prev_node):
            self.__prev = prev_node

        def is_last(self):
            return self.next()==None

    def __init__(self):
        '''Sets up an empty linked list.'''
        self.__head = DoubleLinkedList.ListNode()
        self.__tail = DoubleLinkedList.ListNode()
        self.__head.set_next(self.__tail)
        self.__tail.set_prev(self.__head)

    def first(self):
        return self.__head.next()

    def last(self):
        return self.__tail.prev()

    def append(self, list_node):
        list_node.set_next(self.__tail)
        list_node.set_prev(self.__tail.prev())
        self.__tail.set_prev(list_node)
        list_node.prev().set_next(list_node)

########################################

class MyData(DoubleLinkedList.ListNode):
    def __init__(self, d):
        DoubleLinkedList.ListNode.__init__(self)
        self.__data = d

    def get_data(self):
        return self.__data

ll = DoubleLinkedList()

md1 = MyData(1)
md2 = MyData(2)
md3 = MyData(3)

ll.append(md1)
ll.append(md2)
ll.append(md3)

node = ll.first()
while not node.is_last():
    print("Data [%s]" % node.get_data())
    node = node.next()
于 2012-04-23T12:20:37.680 回答