如果您只会添加边缘而不删除它们,请考虑通过使图形也具有disjoint set semantics来解决此问题。创建新边缘时,首先检查两个节点是否已经属于同一组。如果他们不是,你会创建链接并在集合上执行联合。
下面是一些Python代码,我希望这些代码足够接近伪代码,即使您不知道Python也可以理解。
class Node:
# constructor
def __init__(self):
self.setParent = None
self.graphParents = []
self.graphChildren = []
# disjoint set operations
def getSetRoot(self):
if self.setParent == None:
return self
else:
self.setParent = self.setParent.getSetRoot()
return self.setParent
def joinSet(self, other):
other.getSetRoot().setParent = self.getSetRoot()
# graph operation
def addChild(self, child):
if self.getSetRoot() == child.getSetRoot():
raise ValueError("Cannot add child!")
else:
self.graphChildren.append(child)
child.graphParents.append(self)
self.joinSet(child)
正如我所说,这只适用于如果你永远不会删除任何边缘。这样做需要为新分离的图段重建不相交集,这可能非常缓慢。如果你只会很少移除边缘(比你增加的次数要少很多倍),走这条路可能还是合理的。
这似乎相当于询问节点A和B是否有任何共同的祖先。 –
是的。难点在于A和B都有一棵祖先的树:它不是一个跑在“简单树”中的“孩子”链上的问题。 – PaulMurrayCbr
开始想到它 - 循环的检测也比简单的树形图更复杂。 – PaulMurrayCbr