Assuming that you are interpreting the heaviest path as being a path that always begins with the root of the tree and descends down to a single leaf. You could try merging the weight-finding and path-building operations:
def heavy_path(node):
if not node
return (0,[])
[lweight,llist] = heavy_path(node.left)
[rweight,rlist] = heavy_path(node.right)
if lweight>rweight:
return (node.val+lweight,[node.val]+llist)
else:
return (node.val+rweight,[node.val]+rlist)
Or using a time-honoured technique to speed up this kind of calculation through Memoization. Once you've used memoization once, you could just keep the pathweight values up to date as you alter your tree.
def weight(node):
if node == None:
return 0
node.pathweight=node.val+max(weight(node.left),weight(node.right))
return node.pathweight
def heavy_edge(node):
if not node.left:
lweight=0
else:
lweight=node.left.pathweight
if not node.right:
rweight=0
else:
rweight=node.right.pathweight
if lweight>rweight:
return [node.val,heavy_edge(node.left)]
else:
return [node.val,heavy_edge(node.right)]
weight(t) #Precalculate the pathweight of all the nodes in O(n) time
heavy_edge(T) #Use the precalculated pathweights to efficient find list the heaviest path in O(lg n) time