Недавно я задал вопрос о правильном способе создания класса на С++ 11. Я тренировался, Tree
класс Tree
, и я получил замечательный совет. Тем не менее, я немного затрудняюсь понять, почему мой код не работает.
В частности, мне трудно понять, почему мой метод insert
работает неправильно.
template<typename T>
class Tree {
private:
struct Node {
T data;
Node* p_left;
Node* p_right;
};
Node* newNode(T data) { return new Node {data, nullptr, nullptr}; }
Node* root_;
//Other functions, etc... (copy constructor and copy assignment operator)
public:
void insert(T const data) {
Node*& root = root_;
while (root != nullptr) {
root = (data <= root->data ? root->p_left : root->p_right);
}
root = newNode(data);
}
Tree(): root_(nullptr) {}
//Other constructors, functions, etc...
};
Если я создаю новый объект Tree
, а затем заполняю этот объект некоторыми данными, объект сохраняет только последний кусок вставленных данных. Я знаю, что я что-то испортил из-за ссылки на указатель, но я не могу понять, где. Любые советы в правильном направлении были бы высоко оценены.
Два вопроса... во-первых, при первой вставке в Дерево вы не обновляете root
:
if (root == nullptr) { return newNode(data); }
Фактически, вы возвращаете новый узел, хотя функция insert
возвращает void
. Если вы полностью удалите эту строку, код должен работать. Если root
запускается как nullptr
, цикл while будет пропущен, а root
будет обновлен до нового узла.
Вторая проблема заключается в том, что вы используете ссылку на указатель узла, что означает, что вы перемещаете свой root_
дерева каждый раз, когда вы создаете новый узел. Это не обязательно хорошая идея. Лично я бы написал так:
void insert(T const data) {
Node** proot = &root_;
while (*proot != nullptr) {
proot = (data <= (*proot)->data ? (*proot)->p_left : (*proot)->p_right);
}
*proot = newNode(data);
}
root_
он не должен назначать его root_
?
root
был Node*&
to root_
. Вызывает другую проблему, потому что ссылки не могут быть перенаправлены.