简体   繁体   中英

How to list the longest path in binary tree?

Here we are trying to list the longest path in a binary tree. For instance,

list_longest_path(None)

[]

list_longest_path(BinaryTree(5))

[5]

b1 = BinaryTree(7)

b2 = BinaryTree(3, BinaryTree(2), None)

b3 = BinaryTree(5, b2, b1)

list_longest_path(b3)

[5, 3, 2]

My code is at bottom. Apparently the code returns every node in the tree. Here I am having difficulty on how to generate all lists while using max() at the same time?

class BinaryTree:
"""
A Binary Tree, i.e. arity 2.

=== Attributes ===
@param object data: data for this binary tree node
@param BinaryTree|None left: left child of this binary tree node
@param BinaryTree|None right: right child of this binary tree node
"""

def __init__(self, data, left=None, right=None):
    """
    Create BinaryTree self with data and children left and right.

    @param BinaryTree self: this binary tree
    @param object data: data of this node
    @param BinaryTree|None left: left child
    @param BinaryTree|None right: right child
    @rtype: None
    """
    self.data, self.left, self.right = data, left, right

def __eq__(self, other):
    """
    Return whether BinaryTree self is equivalent to other.

    @param BinaryTree self: this binary tree
    @param Any other: object to check equivalence to self
    @rtype: bool

    >>> BinaryTree(7).__eq__("seven")
    False
    >>> b1 = BinaryTree(7, BinaryTree(5))
    >>> b1.__eq__(BinaryTree(7, BinaryTree(5), None))
    True
    """
    return (type(self) == type(other) and
            self.data == other.data and
            (self.left, self.right) == (other.left, other.right))

def __repr__(self):
    """
    Represent BinaryTree (self) as a string that can be evaluated to
    produce an equivalent BinaryTree.

    @param BinaryTree self: this binary tree
    @rtype: str

    >>> BinaryTree(1, BinaryTree(2), BinaryTree(3))
    BinaryTree(1, BinaryTree(2, None, None), BinaryTree(3, None, None))
    """
    return "BinaryTree({}, {}, {})".format(repr(self.data),
                                           repr(self.left),
                                           repr(self.right))

def __str__(self, indent=""):
    """
    Return a user-friendly string representing BinaryTree (self)
    inorder.  Indent by indent.

    >>> b = BinaryTree(1, BinaryTree(2, BinaryTree(3)), BinaryTree(4))
    >>> print(b)
        4
    1
        2
            3
    <BLANKLINE>
    """
    right_tree = (self.right.__str__(
        indent + "    ") if self.right else "")
    left_tree = self.left.__str__(indent + "    ") if self.left else ""
    return (right_tree + "{}{}\n".format(indent, str(self.data)) +
            left_tree)

def __contains__(self, value):
    """
    Return whether tree rooted at node contains value.

    @param BinaryTree self: binary tree to search for value
    @param object value: value to search for
    @rtype: bool

    >>> BinaryTree(5, BinaryTree(7), BinaryTree(9)).__contains__(7)
    True
    """
    return (self.data == value or
            (self.left and value in self.left) or
            (self.right and value in self.right))

def list_longest_path(node):
"""
List the data in a longest path of node.

@param BinaryTree|None node: tree to list longest path of
@rtype: list[object]

>>> list_longest_path(None)
[]
>>> list_longest_path(BinaryTree(5))
[5]
>>> b1 = BinaryTree(7)
>>> b2 = BinaryTree(3, BinaryTree(2), None)
>>> b3 = BinaryTree(5, b2, b1)
>>> list_longest_path(b3)
[5, 3, 2]
"""
if node is None:
    return []
elif not node.left and not node.right:
    return [node]
else:
    return [node]+list_longest_path(node.left)+list_longest_path(node.right)

The longest path in a tree, is called " diameter ". So you are looking for something like a "python tree diameter calculator" .

You can see the implementation of the algorithm here:

http://www.geeksforgeeks.org/diameter-of-a-binary-tree/

and here:

http://tech-queries.blogspot.com.br/2010/09/diameter-of-tree-in-on.html


Since this website contains only code in C and JAVA, you could take a look here to get some pythonic coding ideas:

Optimize finding diameter of binary tree in Python

Here's a Python function that will return the path:

def list_longest_path(root):
    if not root:
        return []

    l = list_longest_path(root.left)
    r = list_longest_path(root.right)

    if len(l) > len(r):
        return [root] + l
    else:
        return [root] + r

In your code there's no need to check if left or right child exists since your function will return list in any case. What you need to do though is to check the length of the lists returned from children an pick the one that is longer.

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