Skreślenie w binarne drzewo poszukiwań

głosy
0

kiedy więc usunę w binarne drzewo poszukiwań, muszę mieć jak 7 różnych przypadków, tj

  1. Lewy liści;
  2. Prawo liści;
  3. Lewa dziecku tylko lewy dziecka. // czyli węzeł zostać usunięte jest lewa dzieckiem swojego rodzica i pozostawił tylko dziecko.
  4. Dziecko z lewej tylko prawe dziecka.
  5. Prawo dziecka tylko z lewej dziecka.
  6. Prawo dziecka tylko z prawej dziecka.
  7. Węzeł zostać usunięte zostały zarówno dzieci, czyli na prawo i lewo.

Teraz, gdy ten kod jest przy użyciu if-elserobi się dość nieprzyjemny .. Czy jest jakiś inny sposób to zrobić.

Tu jest mój urywek kodu

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;
}
Utwórz 30/09/2011 o 06:10
źródło użytkownik
W innych językach...                            


3 odpowiedzi

głosy
1

Usuwanie pustego wskaźnika nie ma złego wpływu. Tak, powinieneś być w stanie zrobić to bez szczególnych przypadkach. Podstawowym elementem jest po prostu:

delete current->left;
delete current->right;
Odpowiedział 30/09/2011 o 06:14
źródło użytkownik

głosy
3

Można zachować to dużo prostsze niż to, i po prostu ograniczyć się do trzech przypadkach podczas usuwania węzła z BST (binarne drzewo poszukiwań):

  1. węzeł bezdzietny (liść): wystarczy je usunąć - nic specjalnego do zrobienia
  2. węzeł z jednym dzieckiem: usunąć ją i przesunąć dziecko w jego miejsce
  3. węzeł dwoje dzieci: zamienić ją albo jego poprzednika rzędu lub następcy, a następnie usunąć

Strona wiki zawiera przykład jak to może wyglądać w kodzie.

Lub jako bardzo prosty przykład 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);
}
Odpowiedział 30/09/2011 o 06:18
źródło użytkownik

głosy
2

I naprawdę nie rozumiem protokół używany do usuwania tutaj. Wydajesz się nie mieć binarną „Szukaj” drzewa (bez zamawiania w drzewie).

Ale po prostu zrobić prostego kodu. Można zrobić coś takiego:

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;
}

Ponadto, należy użyć usunąć , aby uniknąć przecieków pamięci tutaj. Nadzieję, że pomaga.

Odpowiedział 30/09/2011 o 06:33
źródło użytkownik

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