Не заполняется двоичное дерево

#include <iostream>

using namespace std;

struct Tree{
    int value;
    Tree* left;
    Tree* right;
};

Tree* Add(Tree* a, int elem) {
        if (!a) {
            a = new Tree;
            a->value = elem;
            a->left = NULL;
            a->right = NULL;
            return 0;
        }
        else if (elem < a->value) {
            Add(a->left, elem);
        }
        else  {
            Add(a->right, elem);
        }
        return a;
}
void printTree(Tree* a) {
    if (a) {

        printTree(a->left);
        cout << a->value;
        printTree(a->right);

    }
    else return;
}

int main()
{
    int x;
    int n;
    cin >> n;
    Tree* tree = NULL;
    for (int i = 0; i < n; i++) {
        cin >> x;
        Add(tree, x);
    }
    printTree(tree);
}

Не заполняется двоичное дерево. Что тут не так?


Ответы (2 шт):

Автор решения: MBo

Указатель вы в функцию передаёте по значению, поэтому после её отработки внешняя функция ничего не знает о том, как он изменился внутри. Передавайте по ссылке:

Tree* Add(Tree*& a, int elem)
→ Ссылка
Автор решения: DmitryK

Лучше разделить понятия дерево и узел дерева. Сейчас у вас "дерево" это просто указатель на вершину. И в функцию нужно передавать ссылку/указатель на дерево, в которое вы хотите вставить элемент. Вряд ли бы Вы в таком случае допустили бы ошибку с копией указателя.
Ещё в дереве можно держать размер дерева - ускоряет различные проверки.
Будет наглядней, если сделать что-то типа:

struct MyTreeNode{
    int value;
    MyTreeNode* left = nullptr;
    MyTreeNode* right = nullptr;
};

struct MyTree 
{
  MyTreeNode *Head = nullptr;
  int Size = 0;
};

void Add(MyTree& Tree, int elem) 
{
   if (Tree.Head == nullptr) // или if(Tree.Size == 0)
   {
      MyTreeNode *a = new MyTreeNode;
      a->value = elem;
      a->left = nullptr;
      a->right = nullptr;
      Tree.Head = a;
      Tree.Size++; 
      return;
    }
  ...
}
→ Ссылка