简体   繁体   English

为什么删除功能不能将节点从BST中删除?

[英]Why won't my delete function delete the node out of the BST?

I've spent hours trying to figure it out. 我花了数小时试图弄清楚。 I've checked and the delete function does find the node, but when I try to delete it by setting it as null or equal to a child node it doesn't change the tree at all when I print it out for a second time. 我已经检查过,并且delete函数确实找到了该节点,但是当我尝试通过将其设置为null或等于子节点来删除它时,当我第二次将其打印出来时,它根本不会改变树。 Can anyone help me figure out what I've done wrong or at least guide me to what I need to do to fix it? 谁能帮助我弄清楚我做错了什么,或者至少可以指导我解决该问题需要做些什么?

  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);
      }
    }

The problem is your assumption that setting n to null will remove the node. 问题是您假设将n设置为null将删除该节点。 Consider the following: 考虑以下:

Object x = new Object();

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

This won't modify x . 这不会修改x Java is pass-by-value, where o is the reference to some Object . Java是按值传递,其中o是对某些Object的引用。 You can certainly modify the internals of o through o 's methods: 您当然可以通过o的方法来修改o的内部:

o.setValue(1);

This works because the value of o is really some address on the heap, which isn't being modifed. 之所以可行,是因为o的值实际上是堆上的某个地址,不会被修改。 You can't overwrite o itself (eg, you can't set it to null or a new Object() ). 您不能覆盖o本身(例如,你不能将它设置为空或一个new Object() In order for you to delete a node, you must find the node's parent and set it's left or right child (whichever one you with to remove) and set that to null. 为了删除节点,您必须找到该节点的父节点,并将其设置为左或右子节点(无论您要删除哪个节点)并将其设置为null。 Also, if that node has children, you have to make sure they aren't removed just because their parent is removed. 另外,如果该节点有子节点,则必须确保不会仅由于删除其父节点而将其删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM