Можно ли добавить один узел в дерево так, чтобы дерево осталось деревом бинарного поиска и стало сбалансированным?
Задача: проверить, можно ли добавить один узел в дерево так, чтобы дерево осталось деревом бинарного поиска и стало сбалансированным (определить допустимое значение добавляемого узла);
А. Я попытался решить ее следующим образом:
- Проверять может дерево вообще уже сбалансировано и ничего не надо добавлять
- Идти вниз до уровня пока не обнаружу дисбаланс
- Добавлять узел и проверять сбалансированность. Вот методы, которые я добавил в самодельный класс Tree (заранее говорю, что все методы (такие как Добавление, Обходы и т.п. работают корректно)
public void CheckAndBalanceTree()
{
if (Root == null)
{
Console.WriteLine("Дерево пустое.");
return;
}
if (IsBalanced(Root))
{
Console.WriteLine("Дерево уже сбалансировано.");
return;
}
bool treeBalanced = false;
T optimalValue = default;
Node<T> currentNode = Root;
while (!treeBalanced)
{
int imbalanceLevel = GetImbalanceLevel(Root);
if (imbalanceLevel == -1)
{
Console.WriteLine("Ошибка: Дерево не удалось сбалансировать даже после добавления узла.");
return;
}
if (currentNode.AddForBalancing(optimalValue, out optimalValue))
{
treeBalanced = true;
}
else
{
currentNode = FindNodeAtLevel(Root, imbalanceLevel);
}
}
Console.WriteLine("Дерево сбалансировано добавлением узла со значением: " + optimalValue);
}
private bool IsBalanced(Node<T> root)
{
if (root == null)
{
return true;
}
Queue<Node<T>> queue = new Queue<Node<T>>();
queue.Enqueue(root);
while (queue.Count > 0)
{
Node<T> current = queue.Dequeue();
if (Math.Abs(GetHeight(current.Left) - GetHeight(current.Right)) > 1)
{
return false;
}
if (current.Left != null)
{
queue.Enqueue(current.Left);
}
if (current.Right != null)
{
queue.Enqueue(current.Right);
}
}
return true;
}
public int GetImbalanceLevel(Node<T> node)
{
if (node == null)
{
return 0;
}
int leftHeight = GetImbalanceLevel(node.Left);
int rightHeight = GetImbalanceLevel(node.Right);
if (leftHeight == -1 || rightHeight == -1 || Math.Abs(leftHeight - rightHeight) > 1)
{
return node.Height;
}
return Math.Max(leftHeight, rightHeight) + 1;
}
private Node<T> FindNodeAtLevel(Node<T> node, int targetLevel)
{
if (node == null)
{
return null;
}
if (node.Height == targetLevel)
{
return node;
}
Node<T> leftNode = FindNodeAtLevel(node.Left, targetLevel);
Node<T> rightNode = FindNodeAtLevel(node.Right, targetLevel);
return leftNode ?? rightNode;
}
Я не прошу решить задачу вместо меня, но если честно я не могу придумать даже примерный алгоритм действий, и мне кажется что упомянутый выше план не верен. Как и мой код. Я хочу узнать точный алгоритм, который позволит решить данную задачу, используя методы дерева бинарного поиска