Binarne drzewo poszukiwań Skreślenie (metoda Inorder Pred) C ++

głosy
1

Ok, więc myślałem, że została ustalona, ​​ale jestem coraz całkowicie niespójne wyniki. I przepisał go niby od podstaw, aby rozpocząć świeże i oto moje wyniki. Otrzymuję żadnych błędów, nie zawieszanie, to po prostu nie je usunąć. To po prostu całkowicie bałagan drzewa i daje mi mnóstwo więcej liści i miesza wszystko do góry. Nie wiesz, gdzie pójść

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;
    }
Utwórz 29/10/2008 o 05:56
źródło użytkownik
W innych językach...                            


3 odpowiedzi

głosy
0

Nie powinno być wywołanie remove()rekurencyjne w trzecim przypadku (gdzie „nie wiem, czy to jest prawda” komentarz jest). W przypadku, gdy węzeł usunąć ma dwoje dzieci, co chcesz zrobić, to znaleźć najbardziej po prawej dziecko lewego dziecka (jak robisz; uzyskany węzeł jest przechowywany w parent). Ten węzeł nie ma prawa dziecka - uczynić go tak, że jej dziecko ma prawo prawo dzieckiem węzła ma być usunięty. Następnie wystarczy zmienić rootzmienną jest jego lewa dziecko; nie trzeba zmieniać dataczłonka w dowolnych węzłów lub zadzwonić removerekursywnie.

Na obrazach:

Przed:
         r <- punkty korzeniowe tutaj
       / \
      / \
     ab
    / \ / \
   xcyy
      / \
     xd
        /
       x

Po:
      A <- punkty korzeniowe tutaj
     / \
    xc
       / \
      xd
         / \
        XB
           / \
          yy
Odpowiedział 29/10/2008 o 06:22
źródło użytkownik

głosy
0

Każdy T znaleźć w drzewie unikalny? Wygląda na to, że są z kodu ...

Wygląda jak to powinno działać:

W innym przypadku usuwania węzła głównego:

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;
Odpowiedział 29/10/2008 o 06:57
źródło użytkownik

głosy
1

Co właściwie się dzieje jest to, że pytania były odwrócone może tak byłoby rzeczywiście prostu wracamy rację, ale dane nie zostały naprawdę dopasowane prawidłowo i tak byłoby uderzyć w mur się wydaje.

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

powinien był być

if(x < root->data)
remove(root->left, x);
else
remove(root->right, x);
Odpowiedział 29/10/2008 o 08:09
źródło użytkownik

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