[英]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.