有没有办法为二叉树中的每个节点找到最远的节点。我知道树的diemeter的问题,但是关于每个节点的询问。我想在O(nlogn)
中为n节点树使用算法。
答案 0 :(得分:3)
分两步:
计算每个节点的最远子项及其距离。这可以通过遍历树(O(n))后序来完成。
对于每个节点:检查此节点及其每个父节点的最远子节点(向根节点移动时添加一个额外距离)。挑选最大的。 O(n logn)。
修改:如果您存储了最远的子项及其左右子树的距离,您可以遍历树预订并将所有结果都以O(n)为单位。
示例(没有标记哪个节点是最远的..实现细节):
3.2 root
/ \
1*2 0.1
/ \ \
0.0 1.1 0.0
/ \
0.0 0.0
从根开始 - 通过父项的最长距离为0.
在任何时候都有三种可能性:最长的路线经过父路线,它在左子树或右子树。访问节点时,所有这些距离都很容易获得。
答案 1 :(得分:0)
对于那些对基于Karolys sollution的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与其子女和孙子女有关,也与其父母和祖父母及其他后代有关。我们称之为 nieces
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]