Έχω μια ερώτηση σχετικά με το πώς θα μπορώ να αφαιρέσω ένα παιδί από έναν κόμβο (ρίζα); Επειδή δεν μπορώ να καλέσω την αφαίρεση, αν κάνω το παιδί μηδενική, θα τα παιδιά της παιδικής κινηθεί προς τα επάνω; Όπως, θα ήθελα απλώς να προετοιμαστεί η μηδενική ?? Ή θα έχω επισημάνει στο παιδί του παιδιού;
java δυαδικό δένδρο αναζήτησης
Σε ένα παραδοσιακό δυαδικό δένδρο αναζήτησης, αφαίρεση ενός κόμβου μπορεί να έχει διαφορετικές συνέπειες ανάλογα με το πόσα παιδιά ο κόμβος έχει:
- Ένας κόμβος χωρίς παιδιά μπορεί απλά να αφαιρεθεί
- Ένας κόμβος με ένα παιδί μπορεί να αφαιρεθεί, και ο κόμβος θα αντικατασταθεί από μόνο παιδί της. Αυτό ισχύει ανεξάρτητα από το αν το παιδί είναι μια αριστερή ή δεξιά παιδί.
- Ένας κόμβος με δύο παιδιά έχει μια ελαφρώς πιο περίπλοκη κανόνας: θα πρέπει να βρει το διάδοχο στην παραγγελία ή τον προκάτοχό στην παραγγελία του κόμβου πρέπει να αφαιρεθεί, αντικαταστήστε την αξία του τρέχοντος κόμβου με διάδοχος του ή την αξία του προκατόχου του, στη συνέχεια, διαγράψτε το διάδοχο ή τον προκάτοχό (σύμφωνα με τους κανόνες αυτούς).
Είναι αυτό το σπίτι; Τίποτα δεν πάει καλά με αυτό ... θα ήθελα απλώς να βοηθήσει τους ανθρώπους να μάθουν αντί να πείτε τους τις απαντήσεις.
Αν απλά ρυθμίσετε τον κόμβο παιδί να null θα χάσετε οποιαδήποτε πληροφορία σχετικά με τις παιδιού παιδιά.
Μια τυπική τάξη δέντρο θα γνωρίζουν τα παιδιά του, συνήθως κολλήσει σε έναν πίνακα ή Collection - στην περίπτωση ενός δυαδικού δέντρου, έχετε μόνο δύο άμεσες παιδιά, έτσι, ένα σταθερό μέγεθος συστοιχίας θα λειτουργήσει. Εξαιτίας αυτού του γεγονότος, που συνήθως εφαρμόζουν κάποιο είδος της μεθόδου «removeMe» που το παιδί ζητά για να αφαιρεθεί από τον κατάλογο των παιδιών.
Όπως αναφέρθηκε παραπάνω, αυτό γίνεται περίπλοκο, αν το παιδί που καταργείτε έχει παιδιά.
απάντηση του Tim φαίνεται καλύτερο. Αλλά ναι, θα θελήσετε να κάνετε ένα από τα τρία πράγματα ανάλογα με το είδος του παιδιού είναι αφαίρεση σας. Αν κάνετε ένα παιδί null, τα παιδιά δεν θα κινηθεί προς τα επάνω, γιατί έχετε χάσει αναφορά σε αυτά. Αντ 'αυτού, θα θελήσετε να καθορίσει εάν το αριστερό ή το δικαίωμα των παιδιών του παιδιού αφαίρεση σας θα πρέπει να ρυθμιστεί στη κατάδειξης δείκτη στο παιδί την αφαίρεση σας. Αφού ορίσετε το προηγούμενο κόμβοι δείκτη (αριστερά ή δεξιά) στο παιδί (αριστερά ή δεξιά) του κόμβου αφαίρεση σας, δεν θα έχετε μια αναφορά πια σε αυτό τον κόμβο, έτσι theres δεν χρειάζεται να το θέσει σε null (μπορείτε να» t πρόσβαση πια. Αν δεν έγραψε κάποιο είδος διπλά που συνδέονται με BST, στην οποία περίπτωση που δεν είναι το κλασικό BST)
Αυτός ο κωδικός θα πρέπει να σας βοηθήσει
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));
}
Μπορείτε να κάνετε κάτι σαν αυτό (ψευδοκώδικα):
Λαμβάνοντας υπόψη ένα η ρίζα του δέντρου «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;
}













