我试图从二进制搜索树中删除节点.除了一个特定的情况,我可以成功删除树上的任何其他节点.如果目标节点有2个子节点,并且左子节点具有右子树,我可以找到正确的替换节点并将值切换到目标节点,但是永远不会删除替换节点.
看看上面的图片,如果我尝试删除17,程序将正确导航到13并用13替换17,但它不会删除原来的13,因为它应该.
我附上了我的删除方法和其中引用的方法.
public Node root;
public void delete(int value){
Node node = new Node<>(value);
Node temp;
if(root == null) {
System.out.println("The tree is already empty!"); //tree is empty
return;
}
if (root.value == node.value) { //Root is target value
temp = node.left;
if(temp.right == null){
node.value = temp.value;
temp = null;
}
else{
while(temp.right != null){
temp = temp.right;
}
node.value = temp.value;
temp = null;
}
return;
}
deleteRec(root, node);
}
private void deleteRec(Node lastRoot, Node node){
Node temp;
if (lastRoot.value >= node.value){
if (lastRoot.left.value == node.value){
node = lastRoot.left;
if(node.left == null && node.right == null){ //No children
node = null;
lastRoot.left = null;
}
else if(node.left == null && node.right != null){ //Right Child
lastRoot.left = node.right;
node = null;
lastRoot.left = null;
}
else if(node.left != null && node.right == null){ //Left Child
lastRoot.left = node.left;
node = null;
}
else{ //Two Children
if(node.left.right == null){
node.value = node.left.value;
node.left = node.left.left;
node.left = null;
}
else{
node = findReplacement(node.left);
lastRoot.left.value = node.value;
node.left = null;
}
}
}
else{
deleteRec(lastRoot.left, node);
}
}
else{
if (lastRoot.right.value == node.value){
node = lastRoot.right;
if(node.left == null && node.right == null){ //No Children
node = null;
lastRoot.right = null;
}
else if(node.left == null && node.right != null){ //Right Child
lastRoot.left = node.right;
node = null;
lastRoot.right = null;
}
else if(node.left != null && node.right == null){ //Left Child
lastRoot.right = node.left;
node = null;
}
else{ //Two Children
if(node.left.right == null){
node.value = node.left.value;
node.left = node.left.left;
node.left = null;
}
else{
node = findReplacement(node.left);
lastRoot.left.value = node.value;
node.left = null;
}
}
}
else{
deleteRec(lastRoot.right, node);
}
}
}
private Node findReplacement(Node node) {
while(node.right != null){
node = node.right;
}
return node;
}
这是我的Node类:
public class Node<T> {
public int value;
public Node left;
public Node right;
public Node parent;
public Node(int value) {
this.value = value;
}
}
最佳答案 考虑这部分代码:
Node rep = findReplacement(node.left);
node.value = rep.value;
rep = null;
你找到了替代品,并让代表指向它.然后,基本上你正在做的是使rep指向null.这不会删除节点!父母仍然指着它!
您的代码中有几个地方沿着这些方向做某事.在Java实现中,您希望从树中删除节点的方式是更改父项指向的内容.垃圾收集器负责其他细节.我希望解决这个问题可以帮助您解决问题!