C — Реализация двоичного дерева, вызывающая странное поведение при вставке

#c #recursion #binary-search-tree #dynamic-memory-allocation #function-definition

Вопрос:

У меня есть такая настройка двоичного дерева:

 `
 

Я также инициализирую первый узел BT следующим образом:

 `
 

До этого момента все работало нормально. Однако, когда я пытаюсь вставить в свой BT, я продолжаю получать неожиданное поведение. Моя функция вставки выглядит так.

 `
 

Однако, когда я запускаю код из основной функции и пытаюсь вставить в BT, первый узел отображается просто отлично, но второй узел становится каким-то большим, странным числом. Когда я запускаю его в отладчике, он показывает номер, который я ожидаю, но это не тот номер, который выводится на печать. Вот мой основной метод.

 `
 

Проблема в моей функции вставки, но я не уверен, что происходит не так, потому что, когда я запускаю ее через отладчик, я получаю ожидаемое значение 5 и 6.

Комментарии:

1. Отсутствует возврат в конце вставки

2. malloc(sizeof(struct Node*)) должно быть malloc(sizeof(struct Node)) .

3. Почему initializeTree() Node используется параметр, а не только данные?

4. И если insert() будет создан корневой узел при вставке с NULL корнем, зачем вам вообще это нужно initializeTree() ?

5. @Barмар Да, я только что это понял. Вы совершенно правы!

Ответ №1:

В этих заявлениях

 struct Node* node1 = (struct Node*) malloc(sizeof(struct Node*));
                                                  ^^^^^^^^^^^^
struct Node* node2 = (struct Node*) malloc(sizeof(struct Node*));
                                                  ^^^^^^^^^^^^ 
 

вы неправильно выделяете память. Вместо этого напишите

 struct Node* node1 = (struct Node*) malloc(sizeof(struct Node));
                                                  ^^^^^^^^^^^ 
struct Node* node2 = (struct Node*) malloc(sizeof(struct Node));
                                                  ^^^^^^^^^^^^  
 

Та же проблема существует и в функции insert .

Также внутри функции переместите оператор return в конец функции

 struct Node* insert(struct Node* rootPtr, struct Node* node) {
    if (rootPtr == NULL) {
        rootPtr = (struct Node*) malloc(sizeof(struct Node));
        rootPtr->data = node->data;
        rootPtr->left = NULL;
        rootPtr->right = NULL;
    }

    if (rootPtr->data > node->data) {
        rootPtr->left = insert(rootPtr->left, node);
    } else if (rootPtr->data < node->data) {
        rootPtr->right = insert(rootPtr->right, node);
    }

    return rootPtr;
}
 

Обратите внимание, что передача указателя на весь узел в качестве второго аргумента неэффективна и подвержена ошибкам. Вы могли бы просто передать целое число. Поэтому функция должна быть объявлена следующим образом

 struct Node* insert(struct Node* rootPtr, int data );
 

Комментарии:

1. На этой ноте, в этом заявлении if функции возврата, я думаю, что мой malloc тоже неверен. Позвольте мне попробовать это. Приму ответ через мгновение. На самом деле, я ошибался везде, где называл это. Большое вам спасибо за помощь!