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

2. Впорядковані бінарні дерева (дерева пошуку)

До цього моменту ми розглядали, як можна будувати традиційні і бінарні дерева. На практиці в інформатиці часто використовуються спеціальні варіанти бінарних дерев, які мають певні особливості, такі як порядок, мінімальна глибина та інші. В якості прикладів для корисних властивостей ми можемо дати можливість швидко шукати елемент за заданим значенням (червоно-чорне дерево); задати порядок елементів в дереві (впорядковані дерева пошуку); збалансована глибина (збалансовані дерева); можливість зберігати впорядковане дерево в постійному сховищі, щоб пошук елемента був швидким з якомога меншою кількістю операцій читання (B-дерево) тощо.

Розглянемо спеціальний клас бінарних дерев - впорядковані дерева пошуку (або просто бінарні дерева пошуку).

Бінарне дерево пошуку схоже на звичайне бінарне дерево, але будується за певними правилами:

• У кожного вузла не більше двох нащадків.

• Будь-яке значення яке менше значення вузла стає лівим нащадком або нащадком лівого нащадка.

• Будь-яке значення яке більше або дорівнює значенню вузла стає правим нащадком або нащадком правого нащадка.

Рис. 2. Бінарне дерево пошуку

Зверніть увагу, як зазначені обмеження впливають на структуру дерева. Кожне значення зліва від кореня (8) менше восьми, кожне значення праворуч - більше або дорівнює кореню. Це правило застосовується до будь-якого вузла дерева.

Приклад 2. Реалізація бінарного дерева пошуку

Як і раніше, ми визначимо клас BinaryTreeNode <T>, який описує структуру вузла. Так як нам потрібне впорядковане дерево, слід задати порівняння значень у вузлах. Для цього зробимо клас нащадком інтерфейсу IComparable<T> і реалізуємо потрібні методи.

/// <summary>Представляє вузол дерева </summary>

/// <typeparam name="T">Тип значень вузла

/// </typeparam>

class BinaryTreeNode<T> : IComparable<BinaryTreeNode<T>> where T : IComparable<T>

{

//закриті поля класу

internal T value; // значення вузла

internal BinaryTreeNode<T> parent; // предок вузла

internal BinaryTreeNode<T> leftChild; //лівий нащадок вузла

internal BinaryTreeNode<T> rightChild; //правий нащадок вузла

//конструктор вузла: value - значення вузла

public BinaryTreeNode(T value)

{

if (value == null)

{

throw new ArgumentNullException("Cannot insert null value!");

}

this.value = value;

parent = null;

leftChild = null;

rightChild = null;

}

public override string ToString() { return this.value.ToString(); }

public override int GetHashCode() { return this.value.GetHashCode(); }

public override bool Equals(object obj)

{

BinaryTreeNode<T> other = (BinaryTreeNode<T>)obj;

return CompareTo(other) == 0;

}

public int CompareTo(BinaryTreeNode<T> other)

{

return value.CompareTo(other.value);

}

}

Створимо клас BinarySearchTree, який описує структуру дерева, і реалізуємо в ньому основні алгоритми роботи з цим деревом.

public class BinarySearchTree<T> where T : IComparable<T>

{

//клас бінарного дерева пошуку

private BinaryTreeNode<T> root; // Корінь дерева

//конструктор дерева – створює порожнє дерево

public BinarySearchTree()

{ root = null; }

// Реалізація методів класу

}