我正在编写代码来删除二叉树中的节点。除了“删除root with 2 children”之外,所有情况都有效。 这是我的代码:
Main.java
public class Main {
public static void main(String[] args) {
BinaryTree binaryTree = new BinaryTree();
binaryTree.add(50);
binaryTree.add(40);
binaryTree.add(39);
binaryTree.add(42);
binaryTree.add(41);
binaryTree.add(43);
binaryTree.add(55);
binaryTree.add(65);
binaryTree.add(60);
binaryTree.inOrderTraversal(binaryTree.root);
System.out.println();
binaryTree.removeNode(50);
binaryTree.inOrderTraversal(binaryTree.root);
}
}
BinaryTree.java
public class BinaryTree {
Node root = null;
Node deleteNode = null;
boolean isLeftChild = false;
Node parent = root;
public void add(int d)
{
Node newNode = new Node(d);
if(root!=null)
{
Node futureParent = root;
while(true)
{
if(newNode.data < futureParent.data) //going left
{
if(futureParent.left == null)
{
futureParent.left = newNode;
newNode.parent = futureParent;
break;
}
futureParent = futureParent.left;
}
else
{
if(futureParent.right == null)
{
futureParent.right = newNode;
newNode.parent = futureParent;
break;
}
futureParent = futureParent.right;
}
}
}
else
{
root = newNode;
}
}
public void inOrderTraversal(Node node)
{
if(node!=null)
{
inOrderTraversal(node.left);
System.out.println(node.data);
inOrderTraversal(node.right);
}
}
public void findNode(int n)
{
}
public void removeNode(int n)
{
deleteNode = root;
while(deleteNode!=null)
{
if(n == deleteNode.data)
{
break;
}
parent = deleteNode;
if(n < deleteNode.data)
{
deleteNode = deleteNode.left;
if(deleteNode.data == n)
{
isLeftChild = true;
break;
}
}
else
{
deleteNode = deleteNode.right;
if(deleteNode.data == n)
{
isLeftChild = false;
break;
}
}
}
//Case 1: No children at all
if((deleteNode.left == null)&&(deleteNode.right == null))
{
parent.right = null;
//incomplete code
}
//Case 2:No right child
else if(deleteNode.right == null)
{
deleteNoRightChild();
}
//Case 3:No left child
else if(deleteNode.left == null)
{
deleteNoLeftChild();
}
//Case 4:Both Children
else
{
Node minRightNode = deleteNode.right;
while (minRightNode.left != null)
{
parent = minRightNode;
minRightNode = minRightNode.left;
}
// minRightNode.parent.left = null;
deleteNode.data = minRightNode.data;
deleteNode = minRightNode;
if(minRightNode.left == null)
{
deleteNoLeftChild();
}
else if(minRightNode.right == null)
{
deleteNoRightChild();
}
else if((minRightNode.right == null)&&(minRightNode.left == null))
{
minRightNode.parent.left = null;
}
}
}
private void deleteNoLeftChild() {
if(deleteNode == root)
{
root = deleteNode.right;
}
if(isLeftChild)
{
parent.left = deleteNode.right;
}
else
{
parent.right = deleteNode.right;
}
}
private void deleteNoRightChild() {
if(deleteNode == root)
{ //Case 2.1:deleteNode is root
root = deleteNode.left;
}
if(isLeftChild)
{
//Case 2.2: Case 2, and its a left child
parent.left = deleteNode.left;
}
else
{
//Case 2.3: Case 2, and its a right child
parent.right = deleteNode.left;
}
}
}
Node.java
public class Node {
int data;
Node left;
Node right;
Node parent;
public Node(int d)
{
data = d;
left = null;
right = null;
}
}
正如您所看到的,我正在尝试删除Main.java
中的50。我调试了我的代码,并在我写的deleteNoLeftChild()
例程中跟踪了发出NullPointerException的位置。以下是截图:
请在新标签页中打开图片。
代码窗口中突出显示的蓝线是异常点,因为作业的右侧(deleteNode.right
)不是null
,所以很奇怪。
答案 0 :(得分:0)
问题在于
//Case 4:Both Children
else
{
Node minRightNode = deleteNode.right;
while (minRightNode.left != null)
{
parent = minRightNode;
minRightNode = minRightNode.left;
}
...
}
仅在最小权限节点具有左子节点时才设置父节点。在您的方案中,这不是真的,因此parent
未设置/ null。您可以通过更改树的布局来测试它。