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

ψήφοι
0

Έτσι, όταν μπορώ να διαγράψω το δυαδικό δένδρο αναζήτησης, χρειάζεται να έχουμε σαν 7 διαφορετικές περιπτώσεις, δηλαδή

  1. Αριστερό Φύλλο?
  2. Δικαίωμα Leaf?
  3. Αριστερά παιδί μόνο με αφήσει το παιδί. // δηλαδή ο κόμβος που πρόκειται να διαγραφούν είναι το αριστερό παιδί της είναι η μητρική και έχει αφήσει μόνο παιδί.
  4. Αριστερά παιδί με μόνο το δικαίωμα του παιδιού.
  5. Δικαίωμα του παιδιού με άφησε μόνο παιδί.
  6. Δικαίωμα του παιδιού με μόνο το δικαίωμα του παιδιού.
  7. Κόμβος για να διαγραφούν έχει τόσο τα παιδιά, δηλαδή δεξιά και αριστερά.

Τώρα, όταν αυτός ο κώδικας χρησιμοποιεί if-elseπαίρνει πολύ άσχημη .. είναι οποιοδήποτε άλλο τρόπο για να γίνει αυτό υπάρχει.

Εδώ είναι το απόσπασμα κώδικα μου

if(current->left==NULL && current->right==NULL && current->key<prev->key)   //left leaf
prev->left=NULL;
else if(current->left==NULL && current->right==NULL && current->key>prev->key) // right     leaf
prev->right=NULL;
else if(current->left!=NULL && current->right==NULL && current->key<prev->key) // left     child with one child
prev->left=current->left;
else if(current->left==NULL && current->right!=NULL && current->key<prev->key)
prev->left=current->right;
else if(current->left!=NULL && current->right==NULL && current->key>prev->key)
prev->right=current->left;
else if(current->left==NULL && current->right!=NULL && current->key>prev->key)
prev->right=current->left;
else if(current->left!=NULL && current->right!=NULL)
{
    check=current->right;
    check1=check;
    while(check->left!=NULL)
    {
    check1=check;
    check=check->left;
    }
    *current=*check;
    check1->left=NULL;
}
Δημοσιεύθηκε 30/09/2011 στις 06:10
πηγή χρήστη
Σε άλλες γλώσσες...                            


3 απαντήσεις

ψήφοι
1

Διαγραφή ενός NULL δείκτη δεν έχει αρνητικές επιπτώσεις. Έτσι, θα πρέπει να είναι σε θέση να το κάνουμε αυτό χωρίς ειδικές περιπτώσεις. Το βασικό μέρος είναι απλά:

delete current->left;
delete current->right;
Απαντήθηκε 30/09/2011 στις 06:14
πηγή χρήστη

ψήφοι
3

Μπορείτε να το κρατήσετε πολύ πιο απλό από αυτό, και απλά να περιορίσει τον εαυτό σας σε τρεις περιπτώσεις κατά τη διαγραφή ενός κόμβου από ένα BST (δυαδικό δένδρο αναζήτησης):

  1. ένας κόμβος χωρίς παιδιά (ένα φύλλο): μόλις το αφαιρέσετε - τίποτα το ιδιαίτερο πρέπει να γίνουν
  2. ένας κόμβος με ένα παιδί: αφαιρέστε το και μετακινήστε το παιδί στη θέση του
  3. ένας κόμβος με δύο παιδιά: το swap είτε με τον προκάτοχό στην παραγγελία του ή διάδοχο, και στη συνέχεια αφαιρέστε το

Η σελίδα wiki περιέχει ένα παράδειγμα για το πώς αυτό θα μπορούσε να κοιτάξει στον κώδικα.

Ή ως ένα πολύ βασικό παράδειγμα σε C:

if (current->left==NULL && current->right==NULL) {
    /* leaf node */
    bst_replace(current, NULL);
}
else if (current->left==NULL || current->right==NULL) {
    /* node with one child */
    bst_replace(current, ((current->left) ? current->left : current->right));
}
else {
    /* node with two children */
    Node* successor = bst_next(current);
    current->data = successor->data;
    bst_replace(successor, successor->right);
}
Απαντήθηκε 30/09/2011 στις 06:18
πηγή χρήστη

ψήφοι
2

Δεν καταλαβαίνω πραγματικά το πρωτόκολλο που χρησιμοποιείται για τη διαγραφή εδώ. Φαίνεται να μην έχουν ένα δυαδικό δένδρο «αναζήτησης» (καμία παραγγελία στο δέντρο).

Αλλά για να κάνει ακριβώς το κωδικό απλό. Θα μπορούσατε να κάνετε κάτι σαν αυτό:

bool b1 = (current->left == NULL);
bool b2 = (current->right == NULL);
bool b3 = (current->key > prev->key);

int decision_case = b1 * 4 + b2 * 2 + b3;

switch(decision_case) {
  case 0: // fill in code here
          break;
  ...
  ...
  case 7: // fill in code here
          break;
}

Επίσης, θα πρέπει να χρησιμοποιήσετε τη διαγραφή για να αποφύγετε διαρροές μνήμης εδώ. Ελπίδα που βοηθά.

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

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