python中的递归任意树高度

时间:2016-06-24 02:03:44

标签: python algorithm recursion tree

我正在尝试实现一个递归方法来确定任意树的树高,而不是二叉树。我们给出两个输入,一个是'n'个顶点数。第二行包含n个整数 从-1到n - 1个顶点父项。如果它们中的第i个(0≤i≤n-1)是-1,则顶点i是根,否则它是第i个顶点的父亲的从0开始的索引。保证只有一个根。保证输入代表树。

例如输入是: n = 5 parent = [4,-1,4,1,1] 这意味着节点0是节点4的子节点,节点1是根节点,节点2是节点4的子节点,节点3是节点1(子节点)的子节点,节点4同样是节点1的子节点根。时间:

0 1 2 3 4

4 -1 4 1 1

输出将是3的树的高度。我们给出了一个缓慢的方法,其任务是实现更快的方法。我恐怕无法看到如何将节点输入输入到像:

这样的东西
Height(tree)
if tree = null:
    return 0
else:
    return 1 + Max(Height(tree.child)) 
    # I realise this is a max of one value

提前致谢!

# python3

import sys, threading

sys.setrecursionlimit(10**7) # max depth of recursion
threading.stack_size(2**27)  # new thread will get stack of such size

n = 5
parent = [4, -1, 4, 1, 1]

class TreeHeight:
    def read(self, n, parent):
        self.n = n
        self.parent = parent

    def compute_height(self):
        # Replace this code with a faster implementation    
        maxHeight = 0

        for vertex in range(self.n):
            height = 0
            i = vertex
            while i != -1:
                height += 1
                i = self.parent[i] 
            maxHeight = max(maxHeight, height);

        return maxHeight;

def main():
    tree = TreeHeight()
    tree.read(n, parent)
    print(tree.compute_height())

threading.Thread(target=main).start()

2 个答案:

答案 0 :(得分:2)

我认为可以使用以下代码更快地解决此问题。 我构造树并找到根。然后递归调用该函数,类似于上面的伪代码。

我得到了正确的答案,但是有人可以帮助我了解这是不是一种最佳方法,而且更快?我是编程新手。 据我了解,函数“ compute_height(self)”的时间复杂度为O(n ^ 2),树结构和“ compute_height_nodes”的时间复杂度均为O(n)?

谢谢

`

class Node:
    def __init__(self,name):
    self.key = name
    self.child = []

class TreeHeight:

    def __init__(self):
        self.n = int(input())
        self.input = [int(i) for i in input().split()]
        self.root = None
        self.nodes = []


    def read(self): #construct the tree
        noes = []
        for i in range(self.n): 
            noes.append(Node(i))
        j=0
        for i in self.input:    
            if i != -1:
                noes[i].child.append(noes[j])
            else:
                self.root = noes[j]
            j += 1
        self.nodes = noes

    def compute_height_nodes(self):
        node = self.root
        def Height(node):
            if node is None:
                return 0
            if len(node.child)==0:
                return 1
            else:
                h = []
                for i in range(len(node.child)):
                    h.append(Height(node.child[i]))

            return 1 + max(h)
        return Height(node)


def main():
  tree = TreeHeight()
  tree.read()
  print(tree.compute_height_nodes())

if __name__ == "__main__":
    main()`

答案 1 :(得分:1)

我相信您正在寻找的是memoization

对于每个节点,天真的实现会查看到根的整个路径,存储该高度,然后重复计算它......一遍又一遍。

通过记忆,您可以保留已经完成的计算备忘录:

例如:

节点0的高度为3,但在找到您已找到节点4的高度时,您可以存储该信息(2)。

然后,当你找到节点2的高度时,它的父节点是节点4,你已经知道它是2 ...因此节点2的高度必须是{ {1}}。你不会被迫第二次上树并重新计算所有这些值。