Been trying to solve this for a while now. I've been given a Node in a Disjoint Set.The Node's implementation is as a class where either it has a different parent node or is it's own
class Node {
Node parent;
int rank;
//...constructor and method declarations}
Now, I have to implement the Find method for this class with path compression, called the getParent() method. I wrote the following code:
Node getParent(){
while(parent != this)
{
parent = parent.getParent();
}
return parent;
I get infinite recursion with this code. I know it's problematic, but I do not know how to fix it. I tried using the this
keyword, but it led to the same errors. Please help. Also, an insight on how to write this code in an iterative manner would be a great plus. Also, I would like to restructure the tree such that all intermediate nodes between the node on which the getParent() is called and the root have a common parent ie the root node.
Node getParent() {
while (parent != this) {
parent = parent.getParent();
}
return parent;
}
The problems:
parent
field. Your code should probably be:
Node getParent() {
Node p = parent;
while(p.parent != p) {
p = p.parent;
}
return p;
}
Or recursively:
Node getParent() {
return (parent == this) ? this : parent.getParent();
}
(In this case, the iterative version is safer. You should not get "infinite" recursion, but there is still a risk that you may recurse too deep, with a pathologically deep data structure.)
UPDATE - apparently, it is your intention that getParent
should (incrementally) collapse the parent chain of each Node
it visit. In that case, the recursive solution would be:
Node getParentAndCollapse() {
if (parent == this) {
return this;
} else {
parent = parent.getParentAndCollapse();
return parent;
}
}
An iterative solution that collapses the entire chain requires two traversals of the chain:
parent
fields to refer to the ultimate parent. Something like this
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;
}
The first part of your question is already answered by Stephen, and I think this is complete enough.
About the second part of your question, I assume you have all the nodes in a list. So you have List<Node> allNodes
. The needed method to restructure the tree would be:
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;
}
}
}
The order of this method in the worst case would be O(n^2)
and I did not look for a better way, cause you didn't mention the importance of it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.