Присвоение NULL указателю структуры не работает через функцию. Что делать? - PullRequest
0 голосов
/ 01 мая 2019

Я пытаюсь реализовать удаление BST. Согласно алгоритму, мы можем напрямую удалить лист. Теперь я назначаю NULL для листьев напрямую, и все же этот узел остается таким, как есть.

В тестовом примере, который я дал, попытался удалить лист, и он не работает.

Пожалуйста, помогите!

struct node * delet(long data, struct node* root)
{
    int i=1;
    struct node *temp = root,*t;

    while(temp != 0)
    {
        if(data < temp->data)
        {
            i=2*i;
            temp = temp->l;
        }
        else if(data > temp->data)
        {
            i = (2*i)+1;
            temp = temp->r ;
        }
        else
        {
            printf("%d\n",i);
            break;
        }
    }
    if(temp->l == 0 && temp->r == 0)
    {
        temp = 0;
        return root;
    }
    else if(temp->l == 0)
    {
        temp->data = temp->l->data;
        temp->l = 0;
    }
    else if(temp->r == 0)
    {
        temp->data = temp->r->data;
        temp->r = 0;
    }
    else
    {
        t = temp;
        t = t->r;
        while(t->l != 0)
        {
            t = t->l;
        }
        temp->data = t->data;
        if(t->r != 0)
        {
            t->data = t->r->data;
            t->r = 0;
            return root;
        }
        else
        {
            t = 0;
            return root;
        }
    }
}

1 Ответ

2 голосов
/ 01 мая 2019

temp = 0; не удаляет лист из дерева, просто обнуляет локальную переменную. Вы хотите обнулить некоторые узлы l или r, чтобы удалить узел из дерева. Попробуйте также сохранить родительский элемент, и, как только временная точка указывает на лист, обнулите родительский элемент temp r или l.

.

То же самое относится и к t = 0; позже.

Примечание Комментарий Дэвида о первом освобождении этой памяти ..

Например (при условии, что рут не удаляется):

...
        if(data < temp->data)
        {
            i=2*i;
            parent = temp;
            temp = temp->l;
        }
        else if(data > temp->data)
        {
            i = (2*i)+1;
            parent = temp;
            temp = temp->r ;
        }
        else
        {
            printf("%d\n",i);
            break;
        }
...
    if(temp->l == 0 && temp->r == 0)
    {
        if (parent->l == temp)
             parent->l = 0;
        else
             parent->r = 0;
        // Free temp if needed
        return root;
    }
...

Также обратите внимание, что у вас есть:

    else if(temp->l == 0)
    {
        temp->data = temp->l->data;

Это разыменование нулевого указателя (temp->l равно NULL) и то же самое для temp->r == 0 case.

Тогда у вас есть

         temp->l = 0;

но вы уже в temp->l == 0 деле, так что я не думаю, что это то, что вы имели в виду.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...