Java 替换未排序树中的节点时的无限循环

Java 替换未排序树中的节点时的无限循环,java,recursion,tree,binary-tree,Java,Recursion,Tree,Binary Tree,我正在用Java做一个家庭作业,我必须创建一个未排序的二叉树,其中的字符串作为数据值。然后,我必须编写一个函数,用包含新描述的新对象替换与旧描述匹配的节点和任何重复的节点 下面是我正在使用的代码,包括导致无限循环的测试用例: public class Node { private String desc; private Node leftNode = null; private Node rightNode = null; private int height; public N

我正在用Java做一个家庭作业,我必须创建一个未排序的二叉树,其中的
字符串
作为数据值。然后,我必须编写一个函数,用包含新描述的新对象替换与旧描述匹配的
节点和任何重复的
节点

下面是我正在使用的代码,包括导致无限循环的测试用例:

public class Node {

 private String desc;
 private Node leftNode = null;
 private Node rightNode = null;
 private int height;

 public Node(String desc) {
   this.desc = desc;
   height = 0; // assumes that a leaf node has a height of 0
 }

 public String getDesc() {
  return desc;
 }

 public Node getLeftNode() {
  return leftNode;
 }

 public Node getRightNode() {
  return rightNode;
 }

 public void setLeftNode(Node node) {
   ++height;
   leftNode = node;
 }

 public void setRightNode(Node node) {
   ++height;
   rightNode = node;
 }

 public int getHeight() {
   return height;
 }

 public int addNode(Node node) {
   if(leftNode == null) {
     setLeftNode(node);
     return 1;
   }
   if(rightNode == null) {
     setRightNode(node);
     return 1;
   }
   if(leftNode.getHeight() <= rightNode.getHeight()) {
     leftNode.addNode(node);
     ++height;
   } else {
     rightNode.addNode(node);
     ++height;
   }
   return 0;
 }

 public static void displayTree(Node root) {
   if(root != null) {
     displayTree(root.getLeftNode());
     System.out.println(root.getDesc());
     displayTree(root.getRightNode());
   }
 }

 public static Node findNode(Node current, String desc) {
   Node result = null;
   if(current == null) {
     return null;
   }
   if(current.getDesc().equals(desc)) {
     return current;
   }
   if(current.getLeftNode() != null) {
     result = findNode(current.getLeftNode(), desc);
   }
   if(result == null) {
     result = findNode(current.getRightNode(), desc);
   }
   return result;
 }

 public static void replaceNode(Node root, String oldDesc, String newDesc) {
   if(oldDesc == null || newDesc == null) {
     System.out.println("Invalid string entered");
     return;
   }
   boolean replacedAllNodes = false;
   while(replacedAllNodes == false) {
     Node replace = findNode(root, oldDesc);
     if(replace == null) { // No more nodes to replace
       replacedAllNodes = true;
       return;
     }
     replace = new Node(newDesc);
     root.addNode(replace);
   }
   return;
 }


 public static void main(String[] args) {
     Node root = new Node("test1");
     Node test_2 = new Node("test2");
     Node test_3 = new Node("test3");
     Node test_4 = new Node("test4");
     Node test_5 = new Node("test5");
     Node test_6 = new Node("test6");

     root.addNode(test_2);
     root.addNode(test_3);
     root.addNode(test_4);
     root.addNode(test_5);
     root.addNode(test_6);

     displayTree(root);
     replaceNode(root, "test4", "hey");
     System.out.println("-------");
     displayTree(root);
  }
}
公共类节点{
私有字符串描述;
私有节点leftNode=null;
私有节点rightNode=null;
私人内部高度;
公共节点(字符串描述){
this.desc=desc;
高度=0;//假定叶节点的高度为0
}
公共字符串getDesc(){
返回描述;
}
公共节点getLeftNode(){
返回leftNode;
}
公共节点getRightNode(){
返回右节点;
}
公共void setLeftNode(节点节点){
++高度;
leftNode=节点;
}
public void setRightNode(节点节点){
++高度;
rightNode=节点;
}
公共整数getHeight(){
返回高度;
}
公共int addNode(节点节点){
if(leftNode==null){
setLeftNode(节点);
返回1;
}
if(rightNode==null){
setRightNode(节点);
返回1;
}

如果(leftNode.getHeight()您在while循环中从未更改
root
oldDesc

 while(replacedAllNodes == false) {
     Node replace = findNode(root, oldDesc);
     if(replace == null) { // No more nodes to replace
       replacedAllNodes = true;
       return;
  }
 replace = new Node(newDesc);
 root.addNode(replace);
}
如果你看

public static Node findNode(Node current, String desc) {
   Node result = null;
   if(current == null) {
     return null;
   }
   if(current.getDesc().equals(desc)) {
     return current;
   }
   if(current.getLeftNode() != null) {
     result = findNode(current.getLeftNode(), desc);
   }
   if(result == null) {
     result = findNode(current.getRightNode(), desc);
   }
   return result;
 }
如果
If(current.getDesc().equals(desc))
条件匹配,
replace
将始终是
root
,因此您将陷入while循环

 while(replacedAllNodes == false) {
     Node replace = findNode(root, oldDesc);
     if(replace == null) { // No more nodes to replace
       replacedAllNodes = true;
       return;
  }
 replace = new Node(newDesc);
 root.addNode(replace);
}
更新:

  • 如果不一定要替换整个节点,可以在while循环结束时更新节点的描述
而不是

 replace = new Node(newDesc);
 root.addNode(replace);
做一些类似于:

  root.setDesc(newDesc);
(当然,您必须先创建
setDesc()
方法)

  • 如果必须替换整个对象,则必须如下所示:
而不是

replace = new Node(newDesc);
root.addNode(replace);
这样做:

replace = new Node(newDesc);
replace.setLeftNode(root.getLeftNode);
replace.setRightNode(root.getRightNode);
另外,您必须链接指向
根的节点,使其指向
替换
,如以下示例之一(当然取决于根的哪一侧):


看看你的代码,你不是在替换一个节点,你只是在树的边缘添加了一个新的节点,而旧的节点仍然在那里,所以循环将永远存在,你可以添加一个带有自动递增功能的临时变量,来指示你要替换的节点的级别,你会发现它只是在重复一次同样,与其执行所有这些过程,不如只替换该节点内的描述?

限制之一是我必须用新对象替换该节点,而不仅仅是更改描述:(否则它会变得容易得多。另外,您不应该再次从根节点开始查找下一个节点,为什么不传递您找到的或刚刚替换的节点?好的,首先从旧节点复制左节点和右节点指针,然后从父节点修改指针以指向此新节点,并将其替换。这会使感觉。我想知道我现在能做些什么来正确地将找到的节点切换到具有新描述的新节点。