[英]Problem while implementing Find() method for a disjoint set
一直在尝试解决这一问题。 我得到了一个不相交集合中的节点。该节点的实现是一个类,其中它具有不同的父节点或它自己的
class Node {
Node parent;
int rank;
//...constructor and method declarations}
现在,我必须使用路径压缩为该类实现Find方法,称为getParent()方法。 我写了以下代码:
Node getParent(){
while(parent != this)
{
parent = parent.getParent();
}
return parent;
我得到此代码的无限递归。 我知道这是有问题的,但我不知道如何解决。 我尝试使用this
关键字,但导致了相同的错误。 请帮忙。 此外,对于如何以迭代方式编写此代码的见解也将是一个不错的选择。 另外,我想重构树,以便在调用getParent()的节点与根之间的所有中间节点都具有一个公共父节点,即根节点。
Node getParent() {
while (parent != this) {
parent = parent.getParent();
}
return parent;
}
问题:
parent
字段。 您的代码可能应该是:
Node getParent() {
Node p = parent;
while(p.parent != p) {
p = p.parent;
}
return p;
}
或递归地:
Node getParent() {
return (parent == this) ? this : parent.getParent();
}
(在这种情况下,迭代版本更安全。您不应获得“无限”的递归,但是仍然存在使用病理性深度的数据结构来递归太深的风险。)
更新 -显然,您的意图是让getParent
(逐渐)折叠其访问的每个Node
的父链。 在这种情况下,递归解决方案将是:
Node getParentAndCollapse() {
if (parent == this) {
return this;
} else {
parent = parent.getParentAndCollapse();
return parent;
}
}
折叠整个链的迭代解决方案需要对链进行两次遍历:
parent
字段以引用最终父级。 像这样
Node getParentAndCollapse() {
Node p = getParent(); // iterative version
Node n = this;
while (n.parent != p) {
Node np = n.parent;
n.parent = p;
n = np;
}
return p;
}
斯蒂芬已经回答了您的问题的第一部分,我认为这已经足够完整了。
关于问题的第二部分,我假设您将所有节点都放在列表中。 因此,您具有List<Node> allNodes
。 重组树所需的方法是:
public void reStructureTree(List<Node> allNodes){
for(Node item: allNodes){
Node p = item.parent;
List<Node> branch = new ArrayList<>();
while (p.parent != p){
branch.add(p);
p = p.parent;
}
for(Node branchItem : branch){
branchItem.parent = p;
}
}
}
在最坏的情况下,此方法的顺序为O(n^2)
,我没有寻找更好的方法,因为您没有提到它的重要性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.