简体   繁体   中英

Recursive arbitrary tree height in python

I'm trying to implement a recursive method to determine the tree height of an arbitrary tree, not a binary tree. We are given two inputs one is 'n' the number of vertices. The second line contains n integer numbers from −1 to n − 1 parents of vertices. If the i-th one of them (0 ≤ i ≤ n − 1) is −1, vertex i is the root, otherwise it's 0-based index of the parent of i-th vertex. It is guaranteed that there is exactly one root. It is guaranteed that the input represents a tree.

For example an input is: n = 5 parent = [4, -1, 4, 1, 1] This means that node 0 is a child of node 4, node 1 is the root, node 2 is a child of node 4, node 3 is a child of node 1 (the root) and node 4 is likewise a child of node 1 the root. Since:

0 1 2 3 4

4 -1 4 1 1

The output would be the height of the tree of 3. We are given a slow method an tasked with implementing a faster method. I'm afraid I can't see how to input the node inputs to somethings like:

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

Thanks in advance!

# 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()

I believe what you're looking for is memoization :

The naive implementation, for each node, looks at the entire path to the root, stores that height, then recomputes it... over and over.

With memoization, you keep a memo of calculations you've already done:

For example:

Node 0 has height 3 , but in finding that you already found node 4's height, so you can store that information ( 2 ).

Then, when you find node 2's height, it's parent is node 4, which you already know is 2 ... therefore node 2's height must be 3 . You aren't forced to go up the tree a second time and recompute all those values.

I figured I can solve this problem faster with the following code. I construct the tree and find the root. Then make recursive calls to the function similar to the pseudo-code above.

I get the right answer, but can somebody help me understand if it's an optimal way and faster? I'm pretty new to programming. From my understanding, the time complexity of the function "compute_height(self)" is O(n^2) and the time complexity of the tree construction and "compute_height_nodes" are both O(n)?

Thanks

`

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()`

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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