Binary Search Tree διαγραφή (μέθοδος Inorder Pred) C ++

ψήφοι
1

Εντάξει έτσι σκέφτηκα ότι ήταν σταθερό, αλλά παίρνω εντελώς αντιφατικά αποτελέσματα. Μου ξαναέγραψε το είδος από το μηδέν για να αρχίσει φρέσκο ​​και εδώ είναι τα αποτελέσματά μου. Παίρνω κανένα λάθος, καμία συντριβή, απλά δεν τα αφαιρέσετε. Είναι ακριβώς βρωμίζει εντελώς το δέντρο και μου δίνει έναν τόνο πιο φύλλα, και αναμιγνύει τα πάντα. Δεν είστε σίγουροι πού αλλού να πάει

template <class T>
void BST<T>::remove(struct Node<T>*& root, const T& x)
{
   Node<T>* ptr = root;
   bool found = false;
   Node<T>* parent;


   while (ptr != NULL && !found)
   {
       if (x < ptr->data)
       {
           parent = ptr;
           ptr = ptr->left;
       }
       else if (x > ptr->data)
       {
           parent = ptr;
           ptr = ptr->right;
       }
       else
           found = true;
   }

   if (found == false)
       return;
   else
   {
       if(ptr->left != NULL && ptr->right != NULL)
       {
           Node<T>* inOrderPtr = ptr->left;
           parent = ptr;
           while (inOrderPtr->right != NULL)
           {
               parent = inOrderPtr;
               inOrderPtr = inOrderPtr->right;
           }

           ptr->data = inOrderPtr->data;
           ptr = inOrderPtr;
       }
    Node<T>* subPtr = ptr->left;
    if (subPtr == NULL)
        subPtr = ptr->right;

    else if (parent->left == ptr)
        parent->left = subPtr;

    else
        parent->right = subPtr;

    delete ptr;
    }
Δημοσιεύθηκε 29/10/2008 στις 05:56
πηγή χρήστη
Σε άλλες γλώσσες...                            


3 απαντήσεις

ψήφοι
0

Δεν θα πρέπει να ζητούν remove()αναδρομικά στην τρίτη περίπτωση (όπου το «δεν είναι σίγουρος αν αυτό είναι σωστό» σχόλιο είναι). Σε περίπτωση που ο ο κόμβος να αφαιρέσετε έχει δύο παιδιά, τι θέλετε να κάνετε είναι να βρείτε το σωστό, πιο παιδί του αριστερού παιδιού (όπως κάνετε? Η προκύπτουσα κόμβο αποθηκεύεται σε parent). Αυτός ο κόμβος δεν έχει κανένα δικαίωμα των παιδιών - να είναι τόσο το δικαίωμα του παιδιού της, είναι το δικαίωμα των παιδιών του κόμβου που θέλετε να διαγράψετε. Στη συνέχεια, απλά αλλάξτε τη rootμεταβλητή να είναι αριστερά το παιδί της? Δεν χρειάζεται να αλλάξετε το dataμέλος σε οποιαδήποτε κόμβους ή να καλέσετε removeαναδρομικά.

Σε εικόνες:

Πριν:
         r <- σημεία ρίζα εδώ
       / \
      / \
     ab
    / \ / \
   xcyy
      / \
     XD
        /
       Χ

Μετά:
      α <- σημεία ρίζα εδώ
     / \
    xc
       / \
      XD
         / \
        xb
           / \
          εε
Απαντήθηκε 29/10/2008 στις 06:22
πηγή χρήστη

ψήφοι
0

Το καθένα Τ βρεθεί στο μοναδικό δέντρο; Φαίνεται σαν να είναι από τον κώδικά σας ...

Μοιάζει με αυτό θα πρέπει να εργαστεί:

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

Node<T> *tmp_r = root->left;
Node<T> *parent = root;
while (tmp_r->right != NULL)
{
    parent = tmp_r;
    tmp_r = tmp_r->right;
}
Node<T> *tmp_l = tmp_r;
while (tmp_l->left != NULL)
    tmp_l = tmp_l->left;

tmp_l->left = root->left;
tmp_r->right = root->right;
parent->right = NULL;

parent = root;
root = tmp_r;
delete parent;
Απαντήθηκε 29/10/2008 στις 06:57
πηγή χρήστη

ψήφοι
1

Αυτό που πραγματικά συμβαίνει είναι ότι οι αναζητήσεις θα μπορούσε αντιστράφηκαν έτσι θα ήταν στην πραγματικότητα απλά συνεχίστε σωστά, αλλά τα δεδομένα δεν ήταν πραγματικά ταιριάζουν σωστά και γι 'αυτό θα χτυπήσει έναν τοίχο φαίνεται.

if (root->data < x)
        remove(root->left, x);
    else 
        remove(root->right, x);

θα έπρεπε να είναι

if(x < root->data)
remove(root->left, x);
else
remove(root->right, x);
Απαντήθηκε 29/10/2008 στις 08:09
πηγή χρήστη

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