繁体   English   中英

为不相交集实现Find()方法时出现问题

[英]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;
}

问题:

  1. 您正在更改parent字段。
  2. 您应该测试父母的父母本身是否...不是这个。

您的代码可能应该是:

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;
    }
}

折叠整个链的迭代解决方案需要对链进行两次遍历:

  1. 遍历链找到最终的父级。
  2. 再次遍历链,更新所有parent字段以引用最终父级。
  3. 返回最终的父母。

像这样

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM