My Binary Search Tree program doesn't seem to be deleting anything when I call the deleteNode method. The BST is built perfectly, its just deleting the node part that doesn't work. I call it from my main like this:
System.out.println("Please enter a number you would like to delete from the tre开发者_JS百科e");
temp = reader.nextLine();
try {
int numTemp = Integer.parseInt(temp);
TreeNode treeTemp = bst.deleteNode(numTemp, bst.getRoot());
bst.setRoot(treeTemp);
}
catch(Throwable e){
System.err.println(e);
}
bst.printInBST(bst.getRoot());
In my BinarySearchTree class I implement my deleteNode methods as following:
public TreeNode deleteNode(int x, TreeNode temp){
if(temp != null){
if(x > (int)((Integer)temp.getValue())){
temp.setLeft(deleteNode(new Integer(x), temp.getLeft()));
}
else if(x < (int)((Integer)temp.getValue())){
temp.setRight(deleteNode(new Integer(x), temp.getRight()));
}
else if(temp.getLeft() != null & temp.getRight() != null){
TreeNode temp2 = new TreeNode(temp.getRight().getValue());
while(temp2.getLeft() != null){
temp2 = temp2.getLeft();
}
temp = temp2;
temp.setRight(remove(temp.getRight()));
}
}
return temp;
}
public TreeNode remove(TreeNode temp){
if(temp.getLeft() != null){
temp.setLeft(remove(temp.getLeft()));
return temp;
}
else {
return temp.getRight();
}
}
I think you are not handling the
case 1: where the deleting node is a leaf node
case 2: where the deleting node has just 1 child
the else if part should be something like this.
else if( temp.getLeft() != null && temp.getRight() != null ) // Two children
{
temp.setValue( findMin( temp.getRight() ).getValue());
temp.setRight ( deleteNode( temp.getValue(), temp.getRight() );
}
else
temp = ( temp.getLeft() != null ) ? temp.getLeft() : temp.getRight();
return temp;
The findMin method is to find the inorder successor of the node to be deleted.
private TreeNode findMin( TreeNode t )
{
if( t == null )
return null;
else if( t.getLeft() == null )
return t;
return findMin( t.getLeft() );
}
I hope this answer your question.
Writing legible code makes bugs easier to spot - both by yourself and others. A first step is choosing more expressive variable names than temp
, temp2
, and treeTemp
.
Also, it is really not neccessary to do new Integer(x)
to assign a method parameter of type int
. Simply writing x
instead has the same effect, is faster at runtime, and makes it easier to spot the code that matters.
As for bugs, the first one I see is:
TreeNode temp2 = new TreeNode(temp.getRight().getValue());
That creates a copy of the TreeNode. Changing that copy won't affect the original node. Also, the copy probably doesn't have left
or right
set, since you only pass the value
to the constructor. I wonder why think you need a copy? After all, you don't create one here either:
deleteNode(new Integer(x), temp.getRight())
Next, as Sashwat points out, if the node to delete has less than 2 children, your code doesn't do anything, as none of the conditions in deleteNode
matches.
Not 100% sure if this is your only problem, but should:
else if(temp.getLeft() != null & temp.getRight() != null)
actually be:
else if(temp.getLeft() != null && temp.getRight() != null)
i.e. you only have one & for the "and" operation when you should have two?
public class BSTNode {
…
public boolean remove(int value, BSTNode parent) {
if (value < this.value) {
if (left != null)
return left.remove(value, this);
else
return false;
} else if (value > this.value) {
if (right != null)
return right.remove(value, this);
else
return false;
} else {
if (left != null && right != null) {
this.value = right.minValue();
right.remove(this.value, this);
} else if (parent.left == this) {
parent.left = (left != null) ? left : right;
} else if (parent.right == this) {
parent.right = (left != null) ? left : right;
}
return true;
}
}
精彩评论