Удаление в бинарном дереве поиска

голоса
0

Поэтому, когда я удаляю в бинарном дереве поиска, нужно ли мне иметь как 7 различных случаев т.е.

  1. Левый лист;
  2. Право Лист;
  3. Оставшись ребенком только с левым ребенком. // то есть узел, который будет удален левым ребенок его родитель, и он только оставил ребенок.
  4. Оставшись ребенка только с правом ребенка.
  5. Право ребенок только с левым ребенком.
  6. Право ребенка только с правом ребенка.
  7. Узел, подлежащий исключению как дети, то есть справа и слева.

Теперь , когда этот код использует if-elseэто становится довольно противным .. есть ли другой способ сделать это.

Вот мой фрагмент кода

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;
}
Задан 30/09/2011 в 06:10
источник пользователем
На других языках...                            


3 ответов

голоса
1

Удаление NULL указателя не имеет никакого вредного воздействия. Таким образом, вы должны быть в состоянии сделать это без каких-либо особых случаев. Основная часть просто:

delete current->left;
delete current->right;
Ответил 30/09/2011 в 06:14
источник пользователем

голоса
3

Вы можете держать это намного проще, чем это, и просто ограничивать себя в трех случаях при удалении узла из BST (бинарное дерево поиска):

  1. узел без детей (лист): просто удалить его - ничего особенного должно быть сделано
  2. узел с одним ребенком: удалите его и переместить ребенка в его месте
  3. узел с двумя детьми: поменять его либо его в порядка предшественника или преемника, а затем удалить его

Страница вики содержит пример того , как это может выглядеть в коде.

Или как очень простой пример в 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);
}
Ответил 30/09/2011 в 06:18
источник пользователем

голоса
2

Я не очень понимаю, протокол, используемый для удаления здесь. Вы, кажется, не имеют двоичную «поиск» дерева (без заказа в дереве).

Но просто сделать код простым. Вы могли бы сделать что-то вроде этого:

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

Кроме того , вы должны использовать удалить , чтобы избежать утечек памяти здесь. Надеюсь, это поможет.

Ответил 30/09/2011 в 06:33
источник пользователем

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