繁体   English   中英

将树表示为python中的列表

[英]representing a tree as a list in python

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

将树的节点作为列表存储在python中有什么问题吗? 就像是:

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

其中第0个位置默认为0,默认值为1,而每个位置(i)的2i和2i + 1位置均为子级。 当没有孩子在场时,我们只是处于“无”位置。

我已经阅读了几本书/笔记,其中使用列表列表来表示一棵树,或者比这样的简单列表更复杂的东西,我想知道我在看书时是否存在内在错误?

将二进制树存储为列表没有错,就像用C或Java这样的语言将其存储为平面数组一样。 访问给定节点的父节点非常快,查找子节点也非常有效。

我想很多示例和教程将更喜欢使用“真正树形”的表示形式(列表或对象列表)-解释起来可能会更直观一些。

您当然可以这样做。 我将其定义为使用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]

但是,更大的问题是您为什么要这样做? 是什么使它比列表列表或字典更好? 当您有以下情况时会发生什么:

    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}}}}}}

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

对于合理平衡的密集树,此平面列表方法是合理的。 但是,正如亚当·斯密(Adam Smith)所说,这种类型的平面列表树对于不平衡的稀疏树将变得极为浪费。 假设您有一个分支,有个单身孩子下降了一百层,而树的其余部分什么也没有。 在平面列表树中,您将需要2 ^ 100 + 2 ^ 99 + 2 ^ 98 + ... + 2 ^ 1 +1个点。 在这种情况下,您将用大量的内存来存储可以用嵌套列表更有效地表示的内容。

因此,从本质上讲,使用C语言在平面列表树和嵌套列表树之间进行选择类似于在平面数组树和基于指针的树之间进行选择。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM