首页 文章

从叶子 Build 一个总和树

提问于
浏览
0

嘿,我正在准备考试,我可以使用一些帮助 . 任务是从叶子的值数组(从左到右)构建二进制和树(父节点键是子键的总和),其总是2 ^ n长 . 我首先将数组转换为节点数组 . 然后我做了一个递归函数,它结合了对并在一个新创建的节点数组上调用它自己 . 有没有更好的方法来完成这项任务?也许一个“到位”?例如

输入:[1,2,3,4]

输出:

10
/
3 7
/ \ /
1 2 3 4

class SumTree:
    def __init__(self):
        self.root = None

class Node:
    def __init__(self):
        self.key = 0
        self.parent = None
        self.left = None
        self.right = None

def makeNode(key):
    n = Node()
    n.key = key
    return n

def buildSumTree(array):
    for i in range(len(array)):
        array[i] = makeNode(array[i])
    tree = SumTree()
    tree.root = buildSumTree_rec(array)
    return tree

def buildSumTree_rec(array):
    if len(array) == 1 :
        return array[0]
    else:       
        a = []
        for i in range(0, len(array) // 2, 2):
            n = makeNode(array[i].key + array[i + 1].key)
            n.left = array[i]
            n.right = array[i + 1]
            array[i].parent = n
            array[i + 1].parent = n
            a.append(n)
        return buildSumTree_rec(a)

3 回答

  • 0

    通常是这样的:

    def buildSumTree(array):
        return buildSumTree2(array, 0, len(array))
    
    def buildSumTree2(array, startpos, length):
        if length < 1:
            return None
        if length == 1:
            return makeNode(array[startpos])
        halflen = length/2
        l = buildSumTree2(array, startpos, halflen)
        r = buildSumTree2(array, startpos+halflen, length-halflen)
        n = makeNode(l.key + r.key)
        n.left = l
        n.right = r
        return n
    
  • 0

    以下代码构建从树叶到根的树 . 它重复将两个子节点连接到新创建的父节点,直到只剩下一个节点 .

    class Node:
        def __init__(self, left, right):
            self.left = left
            self.right = right
            self.value = sum(n.value for n in (left, right) if n is not None)
    
        @classmethod
        def create_leaf(cls, value):
            leaf = cls(None, None)
            leaf.value = value
            return leaf
    
    
    INPUT = [1, 2, 3, 4]
    
    nodes = [Node.create_leaf(v) for v in INPUT]
    while len(nodes) > 1:
        inodes = iter(nodes)
        nodes = [Node(*pair) for pair in zip(inodes, inodes)]
    
    root_node = nodes[0]
    

    成对迭代基于:Iterating over every two elements in a list

  • 0

    此实现仅存储叶子而不存储任何其他内容,因此不使用额外的内存来存储节点 . 它也不会改变叶子,即不进行任何改变,只进行读取操作 . 所有其他信息都是即时计算的 . 目前输出是基本的,每深度一行 .

    import math
    
    class SumTree:
    
      def __init__(self, leaves):
        self.leaves = leaves
    
      def nodeAt(self, i, j):
        if i < self.height() - 1:
          return self.nodeAt(i+1, 2*j) + self.nodeAt(i+1, 2*j+1)
        elif i == self.height() - 1:
          return self.leaves[j]
        else:
          raise 'no nodes exists at this depth.'
    
      def nodesAtDepth(self, i):
        return [self.nodeAt(i, j) for j in range(self.widthAtDepth(i))]
    
      def maxWidth(self):
        return self.widthAtDepth(self.height() - 1)
    
      def widthAtDepth(self, i):
        return 2 ** i
    
      def height(self):
        return math.floor(math.log(len(self.leaves), 2)) + 1
    
      def __str__(self):
        result = ''
        width = self.maxWidth()
        for i in range(self.height()):
          result += '{}\n'.format(self.nodesAtDepth(i))
        return result
    
    tree = SumTree(list(range(1, 5)))
    print('leaves', tree.leaves)
    print('height', tree.height())
    print(tree)
    
    <script src="//repl.it/embed/IUUa/2.js"></script>
    

相关问题