有没有办法找到二叉树中每个节点的最远节点。我知道树的直径问题,但那是查询每个节点的问题。我希望有一种算法适用于n个节点的树,并且时间复杂度为 O(nlogn)
。
有没有办法找到二叉树中每个节点的最远节点。我知道树的直径问题,但那是查询每个节点的问题。我希望有一种算法适用于n个节点的树,并且时间复杂度为 O(nlogn)
。
3.2 root
/ \
1*2 0.1
/ \ \
0.0 1.1 0.0
/ \
0.0 0.0
从根开始 - 父节点的最长距离为0。
在任何时刻,有三种可能性:最长路径经过父节点,位于左子树或右子树。当访问节点时,所有这些距离都是容易获得的。
d = min(d(left), d(right), parent.left == this ? parent.d(parent.right) : parent.d(parent.left))
。 - UmNyobe对于那些对Karolys解决方案感兴趣的Python实现:
Python代码:
def getFarGrandChild(node, tree, grandChildren):
winner = None # {'node' : node, 'distance' : 0}
second = None
for child in tree.childrenOf(node):
grandChild = getFarGrandChild(child, tree, grandChildren)
if winner == None or grandChild['distance'] > winner['distance']:
second = winner
winner = grandChild
elif second == None or grandChild['distance'] > second['distance']:
second = grandChild
grandChildren[node] = (winner, second)
if winner == None:
return {'child' : node,
'grandChild' : node,
'distance' : 1}
else:
return {'child' : node,
'grandChild' : winner['grandChild'],
'distance' : winner['distance'] + 1}
A与其子代和孙代相连,也与其父代、祖先及其它后代相连。我们称这些为侄女
Python代码:
def getFarRelative(node, tree, grandChildren, farNodes, niece = None):
winner, second = grandChildren[node]
if niece != None:
if winner == None or niece['distance'] > winner['distance']:
second = winner
winner = niece
elif second == None or niece['distance'] > second['distance']:
second = niece
farNodes[node] = winner
for child in tree.childrenOf(node):
if child != winner['child']:
getFarRelative(child, tree, grandChildren, farNodes,
niece = {'child' :node,
'grandChild' : winner['grandChild'],
'distance' : winner['distance'] + 1})
elif second != None:
getFarRelative(child, tree, grandChildren, farNodes,
niece = {'child' : node,
'grandChild' : second['grandChild'],
'distance' : second['distance'] + 1})
使用以下代码通过from graph import *
# A set of data structures to represent graphs
#
class Node(object):
def __init__(self, name):
self.name = str(name)
def getName(self):
return self.name
def __str__(self):
return self.name
def __repr__(self):
return self.name
def __eq__(self, other):
return self.name == other.name
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
# Override the default hash method
# Think: Why would we want to do this?
return self.name.__hash__()
class Edge(object):
def __init__(self, src, dest):
self.src = src
self.dest = dest
def getSource(self):
return self.src
def getDestination(self):
return self.dest
def __str__(self):
return '{0}->{1}'.format(self.src, self.dest)
class Digraph(object):
"""
A directed graph
"""
def __init__(self):
# A Python Set is basically a list that doesn't allow duplicates.
# Entries into a set must be hashable (where have we seen this before?)
# Because it is backed by a hashtable, lookups are O(1) as opposed to the O(n) of a list (nifty!)
# See http://docs.python.org/2/library/stdtypes.html#set-types-set-frozenset
self.nodes = set([])
self.edges = {}
def addNode(self, node):
if node in self.nodes:
# Even though self.nodes is a Set, we want to do this to make sure we
# don't add a duplicate entry for the same node in the self.edges list.
raise ValueError('Duplicate node')
else:
self.nodes.add(node)
self.edges[node] = []
def addEdge(self, edge):
src = edge.getSource()
dest = edge.getDestination()
if not(src in self.nodes and dest in self.nodes):
raise ValueError('Node not in graph')
self.edges[src].append(dest)
def childrenOf(self, node):
return self.edges[node]
def hasNode(self, node):
return node in self.nodes
def __str__(self):
res = ''
for k in self.edges:
for d in self.edges[str(k)]:
#for d in self.edges[k]:
res = '{0}{1}->{2}\n'.format(res, k, d)
return res[:-1]
if __name__ == '__main__':
# Create a tree :
# root
# / \
# l r
# / \
# ll lr
# / \
# lll lrr
# /
# llll
myTree = Digraph()
myTree.addNode(Node(str('root')))
myTree.addNode(Node(str('l'))) # for left
myTree.addEdge(Edge(Node(str('root')), Node(str('l'))))
myTree.addNode(Node(str('ll'))) # for left, left
myTree.addEdge(Edge(Node(str('l')), Node(str('ll'))))
myTree.addNode(Node(str('lll')))
myTree.addEdge(Edge(Node(str('ll')), Node(str('lll'))))
myTree.addNode(Node(str('llll')))
myTree.addEdge(Edge(Node(str('lll')), Node(str('llll'))))
myTree.addNode(Node(str('lr'))) # for left, right
myTree.addEdge(Edge(Node(str('l')), Node(str('lr'))))
myTree.addNode(Node(str('lrr')))
myTree.addEdge(Edge(Node(str('lr')), Node(str('lrr'))))
myTree.addNode(Node(str('r')))
myTree.addEdge(Edge(Node(str('root')), Node(str('r'))))
grandChildren = {}
getFarGrandChild(Node('root'), myTree, grandChildren)
for key in grandChildren:
print key, grandChildren[key]
print '\n'
farNodes = {}
getFarRelative(Node('root'), myTree, grandChildren, farNodes)
print '\n'
for key in farNodes:
print key, farNodes[key]