Обхід дерева в глибину
// Обхід дерева вглиб (DFS)
public void PrintTreeDFS()
{
PrintTreeDFS(root);
Console.WriteLine();
}
// обхід дерева починається з кореня
private void PrintTreeDFS(BinaryTreeNode<T> node)
{
if (node != null)
{
PrintTreeDFS(node.leftChild);
Console.Write(node.value + " ");
PrintTreeDFS(node.rightChild);
}
}
Повний код класу BinaryTreeNode <T>
public class BinarySearchTree<T> where T : IComparable<T>
{
//клас бінарного дерева пошуку
private BinaryTreeNode<T> root; // Корінь дерева
//конструктор дерева – створює порожнє дерево
public BinarySearchTree()
{ root = null; }
//Методи, які реалізують функціональність дерева
//вставка елемента в бінарне дерево пошуку
public void Insert(T value)
{
root = Insert(value, null, root);
}
// вставка вузла в бінарне дерево пошуку в залежності від значення у вузлі
private BinaryTreeNode<T> Insert(T value, BinaryTreeNode<T> parentNode, BinaryTreeNode<T> node)
{
if (node == null)
{
node = new BinaryTreeNode<T>(value);
node.parent = parentNode;
}
else
{
int compareTo = value.CompareTo(node.value);
if (compareTo < 0)
{
node.leftChild = Insert(value, node, node.leftChild);
}
else if (compareTo > 0)
{
node.rightChild = Insert(value, node, node.rightChild);
}
}
return node;
}
// Пошук - знаходить задане значення в дереві та
/// повертає вузол, що містить це значення, якщо таке існує
private BinaryTreeNode<T> Find(T value)
{
BinaryTreeNode<T> node = this.root;
while (node != null)
{
int compareTo = value.CompareTo(node.value);
if (compareTo < 0)
{ node = node.leftChild; }
else if (compareTo > 0) { node = node.rightChild; } else { break; }
}
return node;
}
// перевіряє, чи є у дереві вузол з вказаним значенням
public bool Contains(T value)
{
bool found = Find(value) != null; return found;
}
//видаляє вузол з дерева за вказаним значенням
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 and 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;
}
}
}
}
// Обхід дерева вглиб (DFS)
public void PrintTreeDFS()
{
PrintTreeDFS(root);
Console.WriteLine();
}
// обхід дерева починається з кореня
private void PrintTreeDFS(BinaryTreeNode<T> node)
{
if (node != null)
{
PrintTreeDFS(node.leftChild);
Console.Write(node.value + " ");
PrintTreeDFS(node.rightChild);
}
}
}
В програмі створюється просте бінарне дерево пошуку, виконується обхід в глибину і викликаються методи пошуку і видалення вузлів.
class Program
{
static void Main(string[] args)
{
BinarySearchTree<string> tree = new BinarySearchTree<string>();
tree.Insert("Telerik");
tree.Insert("Google");
tree.Insert("Microsoft");
tree.PrintTreeDFS(); // Google Microsoft Telerik
Console.WriteLine(tree.Contains("Telerik")); // True
Console.WriteLine(tree.Contains("IBM")); // False
tree.Remove("Telerik");
Console.WriteLine(tree.Contains("Telerik")); // False
tree.PrintTreeDFS(); // Google Microsoft
Console.ReadKey();
}
Приклад 3. Створення бінарного дерева пошуку
class Program
{
static void Main(string[] args)
{
//Бінарне дерево пошуку чисел
BinarySearchTree<int> tree = new BinarySearchTree<int>();
tree.Insert(8);
tree.Insert(4);
tree.Insert(10);
tree.Insert(2);
tree.Insert(3);
tree.Insert(6);
tree.Insert(7);
tree.PrintTreeDFS();
Console.ReadKey();
}
}
Результат обходу: 2 3 4 6 7 8 10
Також, при роботі з бінарними деревами пошуку можна виконувати інші операції.
Приклад 4. Пошук мінімального елемента в дереві пошуку
public T Min()
{
//пошук мін.елемента дерева, починаючи з кореня
return GetMinRecursiv(root);
}
private static T GetMinRecursiv(BinaryTreeNode<T> node)
{
if (node.leftChild == null) //це листок
return node.value;
else
return GetMinRecursiv(node.leftChild);
}
Так як у класі BinarySearchTree<T> не реалізований нумератор (метод GetEnumerator), ми не можемо використовувати оператор цикл foreach, тому доводиться використовувати рекурсію.
