Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
46
Добавлен:
15.01.2021
Размер:
95.81 Кб
Скачать
  1. Видалення вузла

Видалення вузла є найскладнішою операцією з основних операцій дерева бінарного пошуку. Після видалення дерево повинно зберігати свій порядок.

Алгоритм видалення вузла

Перший крок, перш ніж видалити елемент з дерева, - знайти його. Ми вже знаємо, як це відбувається.

Після цього ми маємо 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;

}

}

}