Python基本数据结构实现

时间:2012-04-23 10:23:56

标签: python

我是C ++编码员。最近开始使用Python。我正在看一下Python中的简单链接列表实现。我在这里有点困惑。不仅在这里,而且在树实现等等同样的问题。

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

5 个答案:

答案 0 :(得分: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.html,然后查看解释问题的图片的http://www.experts-exchange.com/Programming/Languages/Scripting/Python/A_7109-Python-basics-illustrated-part-3.html

答案 1 :(得分:1)

初始化self.tail的唯一地方是附加,并在那里将其设置为等于e。稍高于e = Element(x),因此e 是Element类型的对象。请注意,在您调用self.tail.next=e时,您知道head不是none,因此tail也不是None,而是Element的实例。

希望这有帮助。

答案 2 :(得分:1)

您写道:

  

现在接下来是Element类的变量,即使它是公共的,而且Element类的对象也必须访问它。

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

答案 3 :(得分:0)

nexttail 元素,这就是原因。对于任何语言的链表,包括C或C ++,都是如此。 链接列表是使用指针/引用链接在一起的元素列表。

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

答案 4 :(得分: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()