Binary Search Albero Soppressione (metodo Inorder Pred) C ++

voti
1

Ok così ho pensato che è stato fissato, ma sto ottenendo risultati del tutto inconsistenti. Ho riscritto tipo di da zero per iniziare fresco e qui sono i miei risultati. Ottengo nessun errore, nessun crash, semplicemente non li rimuove. E 'appena completamente scombina l'albero e mi dà una tonnellata più foglie, e si mescola il tutto. Non so dove altro andare

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;
    }
È pubblicato 29/10/2008 alle 05:56
fonte dall'utente
In altre lingue...                            


3 risposte

voti
0

Non si dovrebbe essere chiamata remove()in modo ricorsivo nel terzo caso (in cui il "non so se questo è giusto" commento è). Nel caso in cui il nodo di togliere ha due figli, ciò che si vuole fare è trovare il più a destra figlio del figlio sinistro (come si sta facendo, il nodo risultante viene memorizzato in parent). Questo nodo non ha alcun figlio destro - fare in modo che il suo figlio destro è il figlio destro del nodo da cancellare. Poi basta cambiare la rootvariabile per essere il suo figlio sinistro; Non c'è bisogno di cambiare il datamembro in tutti i nodi o per chiamare removein modo ricorsivo.

In foto:

Prima:
         r <- punti di root
       / \
      / \
     ab
    / \ / \
   xcyy
      / \
     xd
        /
       X

Dopo:
      A <- punti di root
     / \
    xc
       / \
      xd
         / \
        xb
           / \
          aa
Risposto il 29/10/2008 a 06:22
fonte dall'utente

voti
0

Sono ciascuno T trovato nell'albero unico? Sembra che essi sono dal codice ...

Sembra che questo dovrebbe funzionare:

Nel caso altro eliminando il nodo radice:

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;
Risposto il 29/10/2008 a 06:57
fonte dall'utente

voti
1

Che cosa realmente stava accadendo è che ricerche che possono sono stati invertiti in modo che sarebbe in realtà solo andare avanti a destra, ma il dato non era davvero abbinando correttamente e quindi sarebbe colpito un muro che sembra.

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

avrebbe dovuto essere

if(x < root->data)
remove(root->left, x);
else
remove(root->right, x);
Risposto il 29/10/2008 a 08:09
fonte dall'utente

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