将树表示为python中的列表

时间:2016-08-25 16:47:26

标签: python binary-tree

我正在学习python,我很好奇人们如何选择在python中存储(二进制)树。

将树的节点存储为python中的列表是否有问题?类似的东西:

[0,1,2,3,4,5,6,7,8]

其中第0个位置默认为0,1是根,对于每个位置(i),2i和2i + 1个位置是子节点。当没有孩子在场时,我们只有一个“没有孩子”。在那个位置。

我已经阅读了几本书/笔记,其中他们使用列表列表代表一棵树,或者比这样简单的列表更复杂的东西,我想知道是否有某种内在的东西我是如何看待它的?

3 个答案:

答案 0 :(得分:0)

将二叉树存储为您正在执行的列表是没有错的 - 它与将其作为C或Java等语言的平面数组存储的想法相同。访问给定节点的父节点非常快,找到子节点也非常有效。

我想很多例子和教程都倾向于使用“树形”的表示形式。 (列表或对象列表) - 解释可能更直观一些。

答案 1 :(得分:0)

你当然可以这样做。我将它定义为一个使用get_children方法从列表派生的类。然而,这是相当难看的,因为A)你必须在O(n)时间内预处理整个列表以将索引与值配对或B)你必须在O(n log n)中调用list.index )时间穿越树。

class WeirdBinaryTreeA(list):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def get_children(value):
        """Calls list.index on value to derive the children"""
        idx = self.index(value)  # O(n) once, O(n log n) to traverse
        return self[idx * 2], self[idx * 2 + 1]


class WeirdBinaryTreeB(list):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.__mapping = self.processtree()

    def processtree(self):
        for idx, val in enumerate(self):
            self.__mapping[val] = idx

    def get_children(value):
        """Queries the mapping on value to derive the children"""
        idx = self.__mapping[value]  # O(1) once, O(n) to traverse
        return self[idx * 2], self[idx * 2 + 1]

然而,更大的问题是为什么你会这样做?是什么让它比列表列表或dicts的词典更好?当你有:

时会发生什么
    A
   / \
      B
     / \
        C
       / \
          D
         / \
            E
           / \
              F

您的列表如下:

[0, 'A', None, 'B', None, None, None, 'C', None, None, None, None, None, None, None, 'D', ...]

而不是:

{"A": {"B": {"C": {"D": {"E": {"F": None}}}}}}

答案 2 :(得分:0)

我在C代码中看到过像这样的表示(你的平面列表/数组),这样的表示也可以在Python中接受,但这取决于你处理的数据的性质。在C代码中,此列表表示中的平衡树可以非常快速地访问(比导航一系列指针快得多),尽管由于所有其他开销,Python中的性能优势可能不太明显。

对于合理平衡的密集树,这种平面列表方法是合理的。然而,正如亚当·斯密评论的那样,这种类型的平面列表树对于不平衡的稀疏树木将变得非常浪费。假设你有一个分支,单个孩子下降一百个级别,树的其余部分什么都没有。平面列表树中需要2 ^ 100 + 2 ^ 99 + 2 ^ 98 + ... + 2 ^ 1 + 1个点。对于这种情况,你会耗费大量的内存,以便用嵌套列表更有效地表示。

因此,实质上,平面列表树与嵌套列表树之间的选择类似于平面数组树和基于指针的树之间的选择。