【问题标题】:Strange NullPointerException in BInary Search Tree二叉搜索树中的奇怪 NullPointerException
【发布时间】:2014-03-03 19:39:38
【问题描述】:

我正在编写代码来删除二叉树中的一个节点。除了“删除带有 2 个孩子的根”情况外,所有情况都有效。 这是我的代码:

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

【问题讨论】:

  • 能否请您也粘贴普通的 NPE 堆栈跟踪?
  • 从变量窗口看,parent 为空,所以parent.right 正在抛出 NullPointerException(不是 deleteNode.right)。
  • @ScottScooterWeidenkopf 它的 IntelliJIDEA 来自 Jetbrains 的 Darcula 主题。出色的 UI!

标签: java nullpointerexception binary-search-tree


【解决方案1】:

问题出在行内

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

仅当最小右节点有左子节点时才设置父节点。在您的情况下,这是不正确的,因此parent 未设置/为空。您可以通过更改树的布局来测试这一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-26
    相关资源
    最近更新 更多