Java BST删除节点时递归函数无法返回正确后继节点值的问题
Java BST删除节点时递归函数无法返回正确后继节点值的问题
兄弟,我看了你的代码,问题主要出在两个地方:一是调用递归函数时没接收返回值,二是找后继节点的逻辑本身有问题,咱们一步步来解决~
第一个问题:Java的值传递导致原变量没更新
你在delete方法里定义了int heir = 0;,然后直接调用findHeir(node, heir);。但Java是值传递,传进函数的是heir的副本,函数内部修改的只是这个副本,原来的heir变量根本不会变,所以最后打印出来还是初始值0。你必须把函数的返回值赋值给heir才行,不过其实这个函数根本不需要传heir参数,咱们后面优化。
第二个问题:findHeir的逻辑错误
你要找的是节点12的后继节点,也就是它右子树的最左节点(也就是19),正确的逻辑应该是:从目标节点的右子树出发,一直往左遍历,直到找到没有左孩子的节点。但你当前的函数逻辑是:只有当当前节点同时有左右孩子时才更新heir,这显然不符合找后继的规则。比如走到节点25时,它没有左右孩子,这时候返回的是之前传过来的heir,但如果右子树结构不同(比如只有左节点),你的逻辑根本不会更新heir,直接返回初始值。
修正方案
1. 重新实现findHeir函数
这里给你两种实现方式,迭代版本更直观,递归版本更简洁:
迭代版本(推荐,效率更高):
// 查找目标节点的后继节点(右子树的最左节点) public static int findHeir(Node node) { Node current = node.rightChild; // 一直往左走,直到没有左孩子 while (current.leftChild != null) { current = current.leftChild; } return current.data; }
递归版本:
// 递归查找右子树的最左节点 public static int findHeir(Node node) { // 终止条件:当前节点没有左孩子,就是后继节点 if (node.leftChild == null) { return node.data; } // 继续往左递归查找 return findHeir(node.leftChild); }
2. 修改delete方法里的调用逻辑
调用findHeir时要传入目标节点的右子树(或者直接传入目标节点,函数内部处理),并且接收返回值,同时补上替换节点值和删除后继节点的逻辑:
//Found the correct node else { //Delete node if it has 2 children if (node.leftChild != null && node.rightChild != null) { // 获取后继节点的值 int heir = findHeir(node); System.out.println("Final node value: " + node.data); System.out.println("Final heir value: " + heir + " (should be 19)"); // 把当前节点的值替换为后继节点的值 node.data = heir; // 删除后继节点:后继节点要么无孩子,要么只有右孩子,直接用delete处理 node.rightChild = delete(node.rightChild, heir); } // 补充处理只有一个孩子或无孩子的情况(你原来的代码漏掉了这部分) else if (node.leftChild == null) { return node.rightChild; } else if (node.rightChild == null) { return node.leftChild; } }
这样修改之后,你就能正确获取到后继节点19,并且完成节点的删除操作了。
备注:内容来源于stack exchange,提问作者user29759326
相关产品推荐
相关产品推荐

