Удаление узла бинарного дерева - C (СИ)
Формулировка задачи:
Бьюсь над задачей битый час, в функцию передаю указатель на узел, который и хотим удалить. И в зависимости от того как удалился возвращаю различные задачи.
вот функция , чистый си
int del(struct treeNode **tempPtr)
{
struct treeNode *ptr=NULL,*ptrX=NULL;
if (*tempPtr == NULL)
return -1;
else if ((*tempPtr)->leftPtr == NULL && (*tempPtr)->rightPtr == NULL){
free(*tempPtr);
*tempPtr = NULL;
tempPtr = NULL;
return 1;
}
else if ((*tempPtr)->leftPtr != NULL && (*tempPtr)->rightPtr == NULL){
ptr = *tempPtr;
*tempPtr = ptr->leftPtr;
free(ptr);
return 2;
}
else if((*tempPtr)->leftPtr == NULL && (*tempPtr)->rightPtr != NULL){
ptr = *tempPtr;
tempPtr=ptr->rightPtr);
free(ptr);
return 3;
}
else {
*ptr = *tempPtr;
ptrX = *tempPtr;
ptr = ptr->leftPtr;
while(ptr->rightPtr != NULL)
ptr=ptr->rightPtr;
if (ptr->leftPtr == NULL ){
tempPtr = &ptr;
ptrX->rightPtr=(*tempPtr)->rightPtr;
ptr = NULL;
}
else {
tempPtr = &ptr;
ptr = ptr->leftPtr ;
ptr->rightPtr = PtrX->rightPtr;
}
free(ptr);
return 4;
}
}Решение задачи: «Удаление узла бинарного дерева»
textual
Листинг программы
void BinaryTree::Remove(int value)
{
Node * pointer = _root;
Node * parent = NULL;
while (pointer != NULL && pointer->value != value)
{
parent = pointer;
if (value < pointer->value)
pointer = pointer->left;
else
pointer = pointer->right;
}
if (pointer != NULL)
{
Node * removed = NULL;
if (pointer->left == NULL || pointer->right == NULL)
{
Node * child = NULL;
removed = pointer;
if (pointer->left != NULL)
child = pointer->left;
else if (pointer->right != NULL)
child = pointer->right;
if (parent == NULL)
_root = child;
else
{
if (parent->left == pointer)
parent->left = child;
else
parent->right = child;
}
}
else // (pointer->left != NULL && pointer->right != NULL)
{
Node * mostLeft = pointer->right;
Node * mostLeftParent = pointer;
while (mostLeft->left != NULL)
{
mostLeftParent = mostLeft;
mostLeft = mostLeft->left;
}
pointer->value = mostLeft->value;
removed = mostLeft;
if (mostLeftParent->left == mostLeft)
mostLeftParent->left = NULL;
else
mostLeftParent->right = NULL;
}
cout << removed << " deleted" << endl;
delete removed;
}
}
Объяснение кода листинга программы
Код удаляет узел из бинарного дерева.
- Переменная
rootсодержит указатель на корень дерева. - Переменная
pointerинициализируется значениемrootи используется для обхода дерева в ширину. - Переменная
parentинициализируется значениемNULLи используется для хранения родительского узла текущего узла. - В цикле
whileпроисходит обход дерева в ширину до тех пор, пока не будет найдено совпадение или не будут проверены все узлы. - Если узел, который нужно удалить, является листовым узлом (у него нет потомков), то он удаляется и заменяется на
NULL. - Если узел имеет только одного потомка, то этот потомк становится новым узлом на месте текущего узла.
- Если узел имеет двух потомков, то нужно найти наиболее левый узел в правой поддереве и заменить текущий узел на этот наиболее левый узел.
- После удаления узла,
pointerиparentсбрасываются вNULL. - Выводится сообщение об удалении узла и сам удаленный узел освобождается с помощью
delete.