簡體   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