BInary搜索树中的奇怪NullPointerException

时间:2014-03-03 19:39:38

标签: java nullpointerexception binary-search-tree

我正在编写代码来删除二叉树中的节点。除了“删除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的位置。以下是截图: Debugger

请在新标签页中打开图片

代码窗口中突出显示的蓝线是异常点,因为作业的右侧(deleteNode.right)不是null,所以很奇怪。

1 个答案:

答案 0 :(得分:0)

问题在于

//Case 4:Both Children
else
{
    Node minRightNode = deleteNode.right;
    while (minRightNode.left != null)
    {
        parent = minRightNode;
        minRightNode = minRightNode.left;
    }
 ... 
}

仅在最小权限节点具有左子节点时才设置父节点。在您的方案中,这不是真的,因此parent未设置/ null。您可以通过更改树的布局来测试它。