当我删除树中不存在的节点时,为什么我的二进制搜索树会崩溃?

时间:2016-12-04 22:42:28

标签: java data-structures tree binary-search-tree

运行main方法时程序崩溃了。我试图删除树中不存在的“Nike”。但是在delete方法内的第一个while循环中,当子变量为null时,该方法将停止执行。当while循环找不到与该元素匹配的任何值时,子变量将运行为null,并且该方法将为“return”,这与结束相同。但是,为什么我的while循环不像我预期的那样工作?

          public class Node
         {
           String value;
           Node leftChild;
           Node rightChild;

           Node(String val,Node left, Node right)
             {
             value = val;
             leftChild = left;
             rightChild = right;
             }

           Node(String val)
           {
           value = val;
           leftChild = null;
           rightChild = null;

           }
       }



      public class binarySearchTree
     {
        Node root;

        binarySearchTree()
        {
        root = null;
        }
       private Node insert(String element, Node bstree)
       {  

       if(root == null)
       {
       root = new Node(element);
       return root;
       }

      if(bstree == null)
      {
      return new Node(element);
      }

     else if(element.compareTo(bstree.value) < 0)
     {
     bstree.leftChild = insert(element,bstree.leftChild);
     }
     else
    {
    bstree.rightChild = insert(element,bstree.rightChild);
    }

   return bstree;
}

 public boolean insert(String element)
{
   insert(element,root);
   return true;
}

 public void delete(String element)
{


    if(root == null)
   {
    System.out.print("Tree is empty");
    return;
   }



   Node child = root;
   Node parent = root;
   while(element.compareTo(child.value) != 0)
   {
      if(child == null)
      {
      System.out.println("Element not found.");
      return;
      }
     else if(element.compareTo(child.value) < 0)
     {
     parent = child;
     child = child.leftChild;
     }
     else 
    {
     parent = child;
     child = child.rightChild;
    }
}

     //if the Node being deleted is the root
     if(child == root)
    {
     if(child.leftChild == null&&child.rightChild == null)
     root = null;
     else if(child.leftChild != null && child.rightChild == null)
     root = root.leftChild;
     else if(child.rightChild != null && child.leftChild == null)
     root = root.rightChild;

     }

    //case 1;
   if(child.leftChild == null&&child.rightChild == null)
   {
      if(parent.leftChild == child)
         parent.leftChild = null;

     else if(parent.rightChild == child)
        parent.rightChild = null;
   }

   //case 2
   if(child.leftChild != null && child.rightChild == null)
   {
      if(parent.leftChild == child)
         parent.leftChild = child.leftChild;

       else if(parent.rightChild == child)
         parent.rightChild = child.leftChild;
   }


   if(child.rightChild != null && child.leftChild == null)
   {
     if(parent.leftChild == child)
        parent.leftChild = child.rightChild;

     else if(parent.rightChild == child)
       parent.rightChild = child.rightChild;
   }


   //case 3
if(child.leftChild != null && child.rightChild != null)
   {
     Node rightMost = child.leftChild;
     Node newLeaf = child;

    if(rightMost.rightChild == null)
    {
      child.value = rightMost.value;
      child.leftChild = null;
    }

    else
    {
    while(rightMost.rightChild != null)
    {
      newLeaf = rightMost;
      rightMost = rightMost.rightChild;
    }

    //swap value
    child.value = rightMost.value;
    newLeaf.rightChild = null;
   }

 }


   class testing
    {
     public static void main(String[] agrs)
      {
      binarySearchTree tree = new binarySearchTree();
      System.out.print("This is the original binary search tree: \n");
      tree.insert("taco");
      tree.insert("banana");
      tree.insert("kiwi");
      tree.insert("pineapple");
      tree.insert("strawberry");
      tree.insert("cookie");
      tree.insert("mango");
      tree.insert("coke");



      tree.delete("coke");
      tree.delete("mango");
      tree.delete("Nike");




 }

}

1 个答案:

答案 0 :(得分:0)

因为在检查child.value是否为空之前,您的代码引用了child。你有这个循环:

while(element.compareTo(child.value) != 0)
{
    if(child == null)
    {
        System.out.println("Element not found.");
        return;
    }
    else if(element.compareTo(child.value) < 0)
    {
        parent = child;
        child = child.leftChild;
    }
    else 
    {
        parent = child;
        child = child.rightChild;
    }
}

第一次循环时,child等于root,并且您知道root不为空。但如果比较失败,则指定一个新的孩子,child = child.rightChildchild = child.leftChild。然后再次进行比较,而不检查child是否为空。如果child为null,则尝试引用child.value会引发异常。

解决这个问题的最简单方法是:

while (child != null && element.compareTo(child.value) != 0)
{
    // do stuff here
}
// moved from inside the loop
if(child == null)
{
    System.out.println("Element not found.");
    return;
}