为什么我的删除功能不会从BST中删除节点?

时间:2013-10-18 22:59:01

标签: java binary-search-tree

我花了好几个小时试图搞清楚。我已经检查过并且删除函数确实找到了节点,但是当我尝试通过将其设置为null或等于子节点来删除它时,当我第二次打印它时它根本不会更改树。任何人都可以帮我弄清楚我做错了什么或者至少指导我做我需要做些什么来修复它?

  class BST {
      Node root; 

      void BST () {
        root = new Node("B");
        insert (root, "A");
        insert (root, "D");
        insert (root, "C"); 
        inOrder (root);

        System.out.println (" ");
        delete (root, "D");
        //root.LEFT = null;
        inOrder (root);
      }

      void insert (Node n, String newKEY) {
        if (n.KEY.compareTo(newKEY) > 0) {

          if (n.LEFT == null) n.LEFT = new Node(newKEY);
          else if (n.LEFT != null && n.LEFT.KEY.compareTo(newKEY) < 0) n.LEFT = new Node(n.LEFT, newKEY, null);
          else insert (n.LEFT, newKEY);
        }

        if (n.KEY.compareTo(newKEY) < 0) {

          if (n.RIGHT == null) n.RIGHT = new Node(newKEY);
          else if (n.RIGHT != null && n.RIGHT.KEY.compareTo(newKEY) > 0) n.RIGHT = new Node(null, newKEY, n.RIGHT);
          else insert (n.RIGHT, newKEY);
        }

        else if (n.KEY.compareTo(newKEY) == 0) n.C++;    
      }

      void delete (Node n, String s) {
        // Visit, check if proper node, if so then delete
        if (n.KEY.compareTo(s) == 0) {
          System.out.println (n.KEY);
          // Deleting a node with no children
          if (n.LEFT == null && n.RIGHT == null) n = null; 

          //  Deleting a node with only left child
          else if (n.RIGHT == null) n = n.LEFT;

          //  Deleting a node with only right child
          else if (n.LEFT == null) n = n.RIGHT; 

          //  Deleting a node with two children
          else deleteNode_Two_Children (n, s);  
        } 
        // Left
        else if (n.KEY.compareTo(s) > 0) delete (n.LEFT, s);
        // Right 
        else if (n.KEY.compareTo(s) < 0) delete (n.RIGHT, s);  

      }

      boolean find (Node n, String s) {
        if (n.KEY.compareTo(s) > 0) {

          if (n.LEFT == null) return false;
          else if (n.LEFT != null && n.LEFT.KEY.compareTo(s) < 0) return false;
          else find (n.LEFT, s);
        }

        if (n.KEY.compareTo(s) < 0) {

          if (n.RIGHT == null) return false;
          else if (n.RIGHT != null && n.RIGHT.KEY.compareTo(s) > 0) return false;
          else find (n.RIGHT, s);
        }

        else if (n.KEY.compareTo(s) == 0) return true;   

        return false;
      }

      void deleteNode_Two_Children (Node n, String st) {
        Node s = getSuccessor(n);
        n = new Node (n.LEFT, s.KEY, s.C, n.RIGHT);
        delete (s, st);

      }

      Node getSuccessor (Node n) {
        Node temp = new Node(); 
        while (n.LEFT != null) {
          temp = n.LEFT; 
          n    = temp;
        }
        return temp; 
      }

      void inOrder (Node n) {   
        // Left
        if (n.LEFT != null) inOrder (n.LEFT);

        // Visit
        System.out.print (n.KEY + " - " + n.C + ", "); 

        // Right 
        if (n.RIGHT != null) inOrder (n.RIGHT);     
      }

      public static void main(String args[]){ 
        BST t = new BST();
        t.BST();
      }  
    }


    class Node {
      String       KEY;
      int          C;  
      Node         LEFT;
      Node         RIGHT;

      Node (String key) {
        KEY     =    key;  
        C       =    1;
        LEFT    =     null;
        RIGHT   =     null;   
      }

      Node (Node L, String key, Node R) {
        LEFT    =     L;
        RIGHT   =     R;
        KEY     =     key;  
        C       =     1;
      }

      Node (Node L, String key, int c, Node R) {
        LEFT    =     L;
        RIGHT   =     R;
        KEY     =     key;  
        C       =     c;
      }

      Node () {
        KEY     =    null;  
        C       =    0;
        LEFT    =     null;
        RIGHT   =     null;   
      }



      // If 'this' is less than 'other', a negative number will be returned, 
      // 0 if equal
      // Positive number if 'this' is greater. 
      int compare (Node other) {
        return this.KEY.compareTo(other.KEY);
      }

      boolean equals (Node other) {
        return this.KEY.equals(other.KEY);
      }
    }

1 个答案:

答案 0 :(得分:0)

问题是您假设将n设置为null将删除该节点。请考虑以下事项:

Object x = new Object();

public void someMethod(Object o) {
    o = null;
}

这不会修改x。 Java是按值传递的,其中o是对某些Object的引用。您当然可以修改oo方法的内部结构:

o.setValue(1);

这是有效的,因为o的值实际上是堆上的某个地址,它没有被修改。您无法覆盖o本身(例如,您无法将其设置为null或new Object())。为了删除节点,您必须找到节点的父节点并设置它的左或右子节点(无论您要移除哪个节点)并将其设置为null。此外,如果该节点有子节点,则必须确保它们不会因为父节点被删除而被删除。