Η διαγραφή ενός κόμβου από μια δυαδική αναζήτηση Δέντρο

ψήφοι
0

Μου πρόγραμμα Binary Search Tree δεν φαίνεται να διαγράψετε κάτι όταν καλώ τη μέθοδο deleteNode. Η BST είναι χτισμένο τέλεια, μόνο του τη διαγραφή του τμήματος του κόμβου που δεν λειτουργεί. Καλώ από την κύρια μου σαν αυτό:

System.out.println(Please enter a number you would like to delete from the tree);
    temp = reader.nextLine();
    try {
        int numTemp = Integer.parseInt(temp);
        TreeNode treeTemp = bst.deleteNode(numTemp, bst.getRoot());
        bst.setRoot(treeTemp);
    }
    catch(Throwable e){
        System.err.println(e);
    }
    bst.printInBST(bst.getRoot());

Στην τάξη BinarySearchTree μου να εφαρμόζουν μεθόδους deleteNode μου ως εξής:

public TreeNode deleteNode(int x, TreeNode temp){
    if(temp != null){
        if(x > (int)((Integer)temp.getValue())){
            temp.setLeft(deleteNode(new Integer(x), temp.getLeft()));
        }
        else if(x < (int)((Integer)temp.getValue())){
            temp.setRight(deleteNode(new Integer(x), temp.getRight()));
        }
        else if(temp.getLeft() != null & temp.getRight() != null){
            TreeNode temp2 = new TreeNode(temp.getRight().getValue());
            while(temp2.getLeft() != null){
                temp2 = temp2.getLeft();
            }
            temp = temp2;
            temp.setRight(remove(temp.getRight()));
        }
    }
    return temp;
}
public TreeNode remove(TreeNode temp){
        if(temp.getLeft() != null){
            temp.setLeft(remove(temp.getLeft()));
            return temp;
        }
        else {
            return temp.getRight();
        }
}
Δημοσιεύθηκε 08/10/2011 στις 18:52
πηγή χρήστη
Σε άλλες γλώσσες...                            


4 απαντήσεις

ψήφοι
0

Δεν είναι 100% σίγουρος αν αυτό είναι μόνο σας πρόβλημα, αλλά θα πρέπει:

else if(temp.getLeft() != null & temp.getRight() != null)

στην πραγματικότητα είναι:

else if(temp.getLeft() != null && temp.getRight() != null)

δηλαδή έχετε μόνο ένα και για το «και» λειτουργία, όταν θα πρέπει να έχετε δύο;

Απαντήθηκε 08/10/2011 στις 19:25
πηγή χρήστη

ψήφοι
2

Νομίζω ότι δεν είναι ο χειρισμός

περίπτωση 1: όπου ο κόμβος διαγραφή είναι ένας κόμβος φύλλο

περίπτωση 2: όταν ο κόμβος διαγραφή έχει μόλις 1 παιδί


το άλλο αν μέρος θα πρέπει να είναι κάτι σαν αυτό.

else if( temp.getLeft() != null && temp.getRight() != null ) // Two children
{
      temp.setValue( findMin( temp.getRight() ).getValue());
      temp.setRight ( deleteNode( temp.getValue(), temp.getRight() );
}
else
     temp = ( temp.getLeft() != null ) ? temp.getLeft() : temp.getRight();

return temp;

Η μέθοδος findMin είναι να βρεθεί η inorder διάδοχο του κόμβου που θέλετε να διαγράψετε.

private TreeNode findMin( TreeNode t )
{
        if( t == null )
            return null;
        else if( t.getLeft() == null )
            return t;
        return findMin( t.getLeft() );
}

Ελπίζω ότι αυτή η απάντηση στην ερώτησή σας.

Απαντήθηκε 08/10/2011 στις 20:39
πηγή χρήστη

ψήφοι
1

Γράφοντας ευανάγνωστο κώδικα κάνει σφάλματα πιο εύκολο να εντοπιστούν - τόσο από τον εαυτό σας και τους άλλους. Ένα πρώτο βήμα είναι η επιλογή πιο εκφραστική ονόματα των μεταβλητών από ό, τι temp, temp2και treeTemp.

Επίσης, δεν είναι πραγματικά απαραίτητες για να κάνουν new Integer(x)για να ορίσετε μια παράμετρο μέθοδο του τύπου int. Απλά γράφοντας xαντί να έχει το ίδιο αποτέλεσμα, είναι ταχύτερη κατά το χρόνο εκτέλεσης, και είναι πιο εύκολο να εντοπίσετε τον κώδικα που έχει σημασία.

Όσο για σφάλματα, το πρώτο που βλέπω είναι:

TreeNode temp2 = new TreeNode(temp.getRight().getValue());

Αυτό δημιουργεί ένα αντίγραφο του TreeNode. Η αλλαγή το αντίγραφο δεν θα επηρεάσει την αρχική κόμβο. Επίσης, το αντίγραφο κατά πάσα πιθανότητα δεν έχει leftή rightπου, από τη στιγμή που περνούν μόνο το valueστον κατασκευαστή. Αναρωτιέμαι γιατί νομίζετε ότι χρειάζεστε ένα αντίγραφο; Μετά από όλα, δεν χρειάζεται να δημιουργήσετε ένα εδώ, είτε:

deleteNode(new Integer(x), temp.getRight())

Στη συνέχεια, όπως Sashwat επισημαίνει, εάν ο κόμβος να διαγράψετε έχει λιγότερο από 2 παιδιά, κωδικός σας δεν κάνει τίποτα, καθώς καμία από τις προϋποθέσεις deleteNodeαγώνες.

Απαντήθηκε 09/10/2011 στις 00:01
πηγή χρήστη

ψήφοι
0
  public class BSTNode {

  public boolean remove(int value, BSTNode parent) {
        if (value < this.value) {
              if (left != null)
                    return left.remove(value, this);
              else
                    return false;
        } else if (value > this.value) {
              if (right != null)
                    return right.remove(value, this);
              else
                    return false;
        } else {
              if (left != null && right != null) {
                    this.value = right.minValue();
                    right.remove(this.value, this);
              } else if (parent.left == this) {
                    parent.left = (left != null) ? left : right;
              } else if (parent.right == this) {
                    parent.right = (left != null) ? left : right;
              }
              return true;
        }
  }
Απαντήθηκε 29/01/2013 στις 18:54
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more