Binært søketre sletting (Inorder Pred metode) C ++

stemmer
1

Ok, så jeg trodde det var løst, men jeg får helt inkonsistente resultater. Jeg skrev den slags fra bunnen av for å starte friskt og her er mine resultater. Jeg får ingen feil, ingen krasj, det bare ikke fjerne dem. Det bare helt søl opp treet og gir meg et tonn flere blader, og blander alt opp. Ikke sikker på hvor andre steder å gå

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;
    }
Publisert på 29/10/2008 klokken 04:56
kilden bruker
På andre språk...                            


3 svar

stemmer
0

Du bør ikke kalle remove()rekursivt i det tredje tilfellet (hvor "ikke sikker på om dette er riktig" kommentar er). I det tilfelle hvor noden å fjerne har to barn, hva du ønsker å gjøre er å finne lengst til høyre barn av den venstre barnet (som du gjør, og den resulterende noden er lagret i parent). Denne noden har ingen rett til barn - gjøre det slik at høyre barnet er rett barnet til noden som skal slettes. Så bare endre rootvariabelen for å være dens venstre barn; uten behov for å endre datamedlem i noen noder eller ringe removerekursivt.

I bilder:

Før:
         r <- rot poeng her
       / \
      / \
     ab
    / \ / \
   xcyy
      / \
     xd
        /
       x

Etter:
      a <- rot poeng her
     / \
    xc
       / \
      xd
         / \
        xb
           / \
          yy
Svarte 29/10/2008 kl. 05:22
kilden bruker

stemmer
0

Hver T funnet i treet unikt? Det ser ut som de er fra koden din ...

Det ser ut som dette skal fungere:

I andre tilfelle slette rotnoden:

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;
Svarte 29/10/2008 kl. 05:57
kilden bruker

stemmer
1

Hva som faktisk skjedde er som kan søkene ble snudd slik at det ville egentlig bare holde det gående rett, men dataene var egentlig ikke samsvarer riktig og så det ville truffet en vegg det virker.

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

Skulle ha vært

if(x < root->data)
remove(root->left, x);
else
remove(root->right, x);
Svarte 29/10/2008 kl. 07:09
kilden bruker

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