Видалення вузла
Видалення вузла є найскладнішою операцією з основних операцій дерева бінарного пошуку. Після видалення дерево повинно зберігати свій порядок.
Алгоритм видалення вузла
Перший крок, перш ніж видалити елемент з дерева, - знайти його. Ми вже знаємо, як це відбувається.
Після цього ми маємо 3 випадки:
1. Якщо вузол - лист - ми вказуємо посилання предка на нуль. Якщо елемент не має предка, це означає, що він є коренем і ми просто його видалимо.
2. Якщо вузол має лише одне під-дерево - ліве або праве, він замінює корінь цього під-дерева.
3. Вузол має два під-дерева. Тоді ми повинні знайти найменший вузол у правому під-дереві та поміняти його. Після цього обміну вузол буде мати одне під-дерево не більше, а потім ми видалимо його на основі деяких з вищезазначених двох правил.
//видаляє вузол з дерева за вказаним значенням
public void Remove(T value)
{
BinaryTreeNode<T> nodeToDelete = Find(value);
if (nodeToDelete != null)
{
Remove(nodeToDelete); //виклик методу, який видаляє вузол
}
}
private void Remove(BinaryTreeNode<T> node)
{
//метод, який видаляє вузол з дерева
// Випадок 3. Якщо вузол має двох нащадків.
if (node.leftChild != null && node.rightChild != null)
{
BinaryTreeNode<T> replacement = node.rightChild;
while (replacement.leftChild != null)
{
replacement = replacement.leftChild;
}
node.value = replacement.value;
node = replacement;
}
// Випадки 1 і 2: Якщо вузол має не більше 1 нащадка
BinaryTreeNode<T> theChild = node.leftChild != null ?
node.leftChild : node.rightChild;
// Якщо елемент, який потрібно видалити, має одного нащадка
if (theChild != null)
{
theChild.parent = node.parent;
// Обробляємо випадок, коли елемент є коренем
if (node.parent == null)
{ root = theChild; }
else
{
// Замінити елемент своїм дочірнім деревом
if (node.parent.leftChild == node)
{
node.parent.leftChild = theChild;
}
else
{
node.parent.rightChild = theChild;
}
}
}
else
{ // Оброблити випадок, коли елемент є коренем
if (node.parent == null)
{
root = null;
}
else
{ // видалити елемент - це лист (не має нащадків)
if (node.parent.leftChild == node)
{
node.parent.leftChild = null;
}
else
{
node.parent.rightChild = null;
}
}
}
