Вы можете использовать базовое c наследование некоторых типов enum и рекурсивных вызовов. Это может быть отправной точкой:
enum NodeType
{
eRoot,
eInternal,
eExternal
};
class BinaryNode
{
public:
virtual NodeType GetType() = 0;
virtual void UpdateTree() = 0;
protected:
BinaryNode* ChildLeft;
BinaryNode* ChildRight;
BinaryNode* Parent;
};
class ExternalNode : public BinaryNode
{
NodeType GetType() override { return eExternal; }
void UpdateTree() override
{
//... Replace node instances here(e.g. delete this node and construct the correct new one given this sub tree. call new InternalNode(this) for example)
// Call this towards the parent node so the tree will be transformed accordingly
}
}
class InternalNode : public BinaryNode
{
NodeType GetType() override { return eInternal; }
void UpdateTree() override { //... }
}
class RootNode : public BinaryNode
{
NodeType GetType() override { return eRoot; }
void UpdateTree() override { //... }
}
Это просто, чтобы дать вам представление, с чего начать. Вы можете проверить тип узла во время выполнения с помощью GetType () и выполнить некоторые проверки на основе этого.
Имейте в виду, что этот вид преобразования не особенно быстр. Если вы хотите, чтобы это было быстро, не используйте разные типы и вызовы виртуальных функций и указатели.
Поместите ваше двоичное дерево в массив и используйте двоичную индексацию, поэтому при заданном индексе «n» используйте 2*n+1
, чтобы получить левого потомка, и 2*n+2
, чтобы получить правого потомка. Затем используйте некоторые флаги (root, внешний, внутренний и c.), Чтобы определить, какие функции вы хотите вызвать на двоичном узле. Я бы не использовал наследование, как в моем примере кода, чтобы быть быстрым или более читабельным. Фактически, внешнее решение о том, какие функции вызывать на узле, может быть намного более читабельным и менее подверженным ошибкам.