2014-10-02 2 views
0

Я пытаюсь добавить элемент в наборе с помощью бинарного дерева:C++: где мои новые узлы?

bool TreeSet::add(const string &str) 
{ 
    if (treesize == 0) 
    { 
     TreeNode->data = str; 
     treesize++; 
     return true; 
    } 
    else 
    { 
     if (str < TreeNode->data) 
      return insert(TreeNode->left, str); 
     else if (str > TreeNode->data) 
      return insert(TreeNode->right, str); 
     else 
      return false; 
    } 
    return false; 
} 

bool TreeSet::insert(TREE *node, const string &str) //private 
{ 
    if (node == NULL) 
    { 
     node = new TREE; 
     node->data=str; 
     node->left = NULL; 
     node->right = NULL; 
     treesize++; 
     return true; 
    } 
    else 
    { 
     if (str < node->data) 
      return insert(node->left, str); 
     else if (str > node->data) 
      return insert(node->right, str); 
     else 
      return false; 
    } 
    return false; 
} 

Как вы можете видеть, я хочу, чтобы инициализировать ВАЛ-структуру внутри вставки и когда я закончу делать это, я хочу, чтобы связать его с левый или правый узел дерева.

Но когда я GdB это только один уровень дерева (верхний уровень) может быть достроено, *left и *right узел не NULL независимо от того, сколько строк я пытался добавить к нему. Зачем?

Мое древа:

typedef struct tree 
{ 
    string data; 
    tree *left; 
    tree *right; 
} TREE; 
+0

Возможно, у вас есть несколько [правил из трех] (http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) проблем. –

ответ

6
bool TreeSet::insert(TREE *node 

должен быть

bool TreeSet::insert(TREE *&node 

Указатели также могут быть переданы по ссылке, и должно быть, если вы намерены изменить их непосредственно. В противном случае вы передаете копию, и теперь у вас есть два указателя, указывающих на одно и то же место. При использовании скопированных один к new некоторым данным, теперь он указует на новое место памяти, оставляя исходный указатель еще как NULL (nullptr в C++ 11)


На стороне записки, когда дерево получает построен, вероятно, вы должны инициализировать left и right к NULL (nullptr в C++ 11):

typedef struct tree 
{ 
    string data; 
    tree *left; 
    tree *right; 
    tree():left(NULL),right(NULL){} 
} TREE; 
+0

Спасибо. У меня его конструктор класса инициализируется в NULL. – hlx98007

2

Когда вы передаете указатель в качестве параметра в функции insert как это:

bool TreeSet::insert(TREE* node, const string& str); 

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

node = new TREE; // Points local variable 'node' to newly allocated data. 
       // When the function goes out of scope 'node' will be destroyed 
       // and the memory will be leaked. 

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

bool TreeSet::insert(TREE*& node, const string& str); 

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

Смежные вопросы