java δυαδικό δένδρο αναζήτησης

ψήφοι
0

Έχω μια ερώτηση σχετικά με το πώς θα μπορώ να αφαιρέσω ένα παιδί από έναν κόμβο (ρίζα); Επειδή δεν μπορώ να καλέσω την αφαίρεση, αν κάνω το παιδί μηδενική, θα τα παιδιά της παιδικής κινηθεί προς τα επάνω; Όπως, θα ήθελα απλώς να προετοιμαστεί η μηδενική ?? Ή θα έχω επισημάνει στο παιδί του παιδιού;

Δημοσιεύθηκε 31/10/2009 στις 20:40
πηγή χρήστη
Σε άλλες γλώσσες...                            


6 απαντήσεις

ψήφοι
2

Σε ένα παραδοσιακό δυαδικό δένδρο αναζήτησης, αφαίρεση ενός κόμβου μπορεί να έχει διαφορετικές συνέπειες ανάλογα με το πόσα παιδιά ο κόμβος έχει:

  • Ένας κόμβος χωρίς παιδιά μπορεί απλά να αφαιρεθεί
  • Ένας κόμβος με ένα παιδί μπορεί να αφαιρεθεί, και ο κόμβος θα αντικατασταθεί από μόνο παιδί της. Αυτό ισχύει ανεξάρτητα από το αν το παιδί είναι μια αριστερή ή δεξιά παιδί.
  • Ένας κόμβος με δύο παιδιά έχει μια ελαφρώς πιο περίπλοκη κανόνας: θα πρέπει να βρει το διάδοχο στην παραγγελία ή τον προκάτοχό στην παραγγελία του κόμβου πρέπει να αφαιρεθεί, αντικαταστήστε την αξία του τρέχοντος κόμβου με διάδοχος του ή την αξία του προκατόχου του, στη συνέχεια, διαγράψτε το διάδοχο ή τον προκάτοχό (σύμφωνα με τους κανόνες αυτούς).
Απαντήθηκε 31/10/2009 στις 20:49
πηγή χρήστη

ψήφοι
0

Είναι αυτό το σπίτι; Τίποτα δεν πάει καλά με αυτό ... θα ήθελα απλώς να βοηθήσει τους ανθρώπους να μάθουν αντί να πείτε τους τις απαντήσεις.

Αν απλά ρυθμίσετε τον κόμβο παιδί να null θα χάσετε οποιαδήποτε πληροφορία σχετικά με τις παιδιού παιδιά.

Απαντήθηκε 31/10/2009 στις 20:51
πηγή χρήστη

ψήφοι
0

Μια τυπική τάξη δέντρο θα γνωρίζουν τα παιδιά του, συνήθως κολλήσει σε έναν πίνακα ή Collection - στην περίπτωση ενός δυαδικού δέντρου, έχετε μόνο δύο άμεσες παιδιά, έτσι, ένα σταθερό μέγεθος συστοιχίας θα λειτουργήσει. Εξαιτίας αυτού του γεγονότος, που συνήθως εφαρμόζουν κάποιο είδος της μεθόδου «removeMe» που το παιδί ζητά για να αφαιρεθεί από τον κατάλογο των παιδιών.

Όπως αναφέρθηκε παραπάνω, αυτό γίνεται περίπλοκο, αν το παιδί που καταργείτε έχει παιδιά.

Απαντήθηκε 31/10/2009 στις 21:33
πηγή χρήστη

ψήφοι
0

απάντηση του Tim φαίνεται καλύτερο. Αλλά ναι, θα θελήσετε να κάνετε ένα από τα τρία πράγματα ανάλογα με το είδος του παιδιού είναι αφαίρεση σας. Αν κάνετε ένα παιδί null, τα παιδιά δεν θα κινηθεί προς τα επάνω, γιατί έχετε χάσει αναφορά σε αυτά. Αντ 'αυτού, θα θελήσετε να καθορίσει εάν το αριστερό ή το δικαίωμα των παιδιών του παιδιού αφαίρεση σας θα πρέπει να ρυθμιστεί στη κατάδειξης δείκτη στο παιδί την αφαίρεση σας. Αφού ορίσετε το προηγούμενο κόμβοι δείκτη (αριστερά ή δεξιά) στο παιδί (αριστερά ή δεξιά) του κόμβου αφαίρεση σας, δεν θα έχετε μια αναφορά πια σε αυτό τον κόμβο, έτσι theres δεν χρειάζεται να το θέσει σε null (μπορείτε να» t πρόσβαση πια. Αν δεν έγραψε κάποιο είδος διπλά που συνδέονται με BST, στην οποία περίπτωση που δεν είναι το κλασικό BST)

Απαντήθηκε 01/11/2009 στις 00:20
πηγή χρήστη

ψήφοι
0

Αυτός ο κωδικός θα πρέπει να σας βοηθήσει

public Node<T> getParentOf(Node<T> child){
    findParentOf(this.root, child);
    return temp;
}

private void findParentOf(Node<T> ROOT, Node<T> child){
    if(ROOT.hasLeft()){
        findParentOf(ROOT.left, child);
    }

    if(ROOT.left == child || root.right == child){
        temp = ROOT;
    }

    if(ROOT.hasRight()){
        findParentOf(ROOT.right, child);
    }
}


private void replaceNode(Node<T> original, Node<T> newNode){
    Node<T> tempParent = getParentOf(original);
    if(original == tempParent.left){
        tempParent.left = newNode;
    }else if(original == tempParent.right){
        tempParent.right = newNode;
    }
}

private void traverseChildrenAndAdd(Node<T> newParent, Node<T> oldParent){
    newParent.insert(oldParent.data);
    if(oldParent.hasLeft()){
        traverseChildrenAndAdd(newParent,oldParent.left);
    }



    if(oldParent.hasRight()){
        traverseChildrenAndAdd(newParent,oldParent.right);
    }
}
private void deleteNode(Node<T> ROOT, Node<T> d){
    if(d.data.compareTo(ROOT.data) < 0){
        deleteNode(ROOT.left, d);
    }else if(d.data.compareTo(ROOT.data) > 0){
        deleteNode(ROOT.right, d);
    }else if(d == this.root){
        if(this.root.hasLeft()){
            traverseChildrenAndAdd(root.left, root.right);
            root = root.left;
        }else if(root.hasRight()){
            root = root.right;
        }else{
            root = null;
        }
    }else{
        if(ROOT.hasLeft()&&ROOT.hasRight()){
            Node<T> successor = getMinNode(ROOT);
            replaceNode(successor, successor.right);
        }else if(ROOT.hasLeft() || ROOT.hasRight()){
            if(ROOT.hasLeft()){
                replaceNode(ROOT, ROOT.left);
            }else{
                replaceNode(ROOT, ROOT.right);
            }
        }else{
            replaceNode(ROOT, null);
        }
    }
}

public void remove(T data){
    deleteNode(this.root, new Node<T>(data));
}
Απαντήθηκε 13/02/2011 στις 10:14
πηγή χρήστη

ψήφοι
0

Μπορείτε να κάνετε κάτι σαν αυτό (ψευδοκώδικα):

Λαμβάνοντας υπόψη ένα η ρίζα του δέντρου «root» και τον κόμβο για να διαγράψει ή ορισμένα στοιχεία «x» κάντε τα εξής

 if x < root
      recurse to left child
 if x > root
      recurse to right child
 else //node found
      find the min item of the node right child //min item should be left most leaf node node
      replace the value of the node you want to delete with min nodes value
      now delete the min node
 return root;

κώδικας:

delete(Node root, Object x){
    if(root == null){
        return null;
    }

    if(data < root.data){
        root = delete(root.left);
    }else if(root.data < data){
        root = delete(root.right);
    }else{
        if(root.left != null && root.right != null){
            Object tmp = findMin(root.right);
            root.data = tmp;
            root.right = delete(root.right, tmp);
        }else{
            return (root.left != null) ? root.left : root.right;    
        }
    }
return root;

}

Απαντήθηκε 09/09/2014 στις 20:33
πηγή χρήστη

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