Я немного изменил свои методы, изменив лист массива [ 1 2 3 ]
на обычный.Это означает, что теперь каждый лист является объектом, который содержит один элемент, поэтому дерево теперь выглядит не так:
1
/ \
[2] [ 3 ]
/ \
[4 , 5 ,6 ,7] [8 , 9 , 10 , 11 ]
, а как:
1
/ \
2 3
/ \ / \
5 6 7 8
Новая структура дерева:
struct SmartTree {
int value;
int childrens;
bool is_root = false;
std::unique_ptr<SmartTree> LeftChild;
std::unique_ptr<SmartTree> RightChild;
};
Но я уверен, что и предыдущий метод будет работать так же хорошо. Так что я обнаружил, что не без помощи хорошим решением в этом случае является рекурсия, а теперь функция, которая проходит по дереву и добавляет элемент вend выглядит так:
std::unique_ptr <SmartTree> InsertLeftChild(std::unique_ptr<SmartTree> tree, std::unique_ptr<SmartTree> left_subtree){
// left_subtree - node to insert
tree -> childrens += 1;
if (tree -> is_root and tree -> LeftChild == nullptr) tree -> LeftChild = std::move(left_subtree);
else if (tree -> is_root) tree -> LeftChild = InsertLeftChild(std::move(tree -> LeftChild) , move(left_subtree));
else if (tree -> LeftChild == nullptr)tree -> LeftChild = std::move(left_subtree);
else if (tree -> RightChild == nullptr) tree -> RightChild = std::move(left_subtree);
else if (tree -> LeftChild -> childrens <= tree -> RightChild -> childrens) tree->LeftChild = InsertLeftChild(std::move(tree -> LeftChild) , std::move(left_subtree));
else if (tree -> LeftChild -> childrens > tree -> RightChild -> childrens) tree->RightChild = InsertLeftChild(std::move(tree -> RightChild) , std::move(left_subtree));
return move(tree);
};
Этот текст написан только для вставки левых детей.Таким образом, первая и вторая if
проверяет, является ли это корнем, и является ли эта корневая инициализация.Если у него есть дочерние элементы, то вызовите функцию InsertLeftChilld
.Передача aruments, функция с перемещением уничтожит предыдущий указатель, поэтому с левой стороны я возвращаю права владения LeftChild:
tree -> LeftChild = std::move(left_subtree);
else if (tree -> LeftChild == nullptr)
проверяет, является ли это концом, и если это так - вставляет новый лист
else if (tree -> LeftChild -> childrens <= tree -> RightChild -> childrens)
проверяет, куда вы должны направить свой лист дальше, если вы не можете его вставить. Надеюсь, этот метод поможет кому-то в будущем. Спасибо всем за ответы!