- •Інформатика
- •Необчислювальні алгоритмы
- •Від автора
- •Створення алгоритму
- •Налагодження алгоритму
- •Допоміжні задачі
- •Поняття систем числення
- •Числова інформація Цілі числа
- •Дійсні числа
- •Текстова інформація Символи
- •Дерево. Бінарне дерево
- •If to nil then with t* do begin
- •Бінарний пошук Пошук діленням навпіл
- •Рекурсивний бінарний пошук
- •Пошук у рядку
- •Скінченні автомати Основні поняття
- •Пошук у мережі
- •Прямі методи сортування Сортування вибором
- •Сортування обміном
- •Шейкерне сортування
- •Сортування методом Шелла
- •Швидке сортування
- •Метод прямого злиття
- •Метод природного злиття
- •Сортування підрахунком
- •Цифрове сортування
- •Література
- •61012, М. Харків, вул. Енгельса, 11.
Дерево. Бінарне дерево
Якщо у списку кожний елемент мае покажчик лише на один наступний за ним елемент, то в дереві — на декілька. Таку структуру можна організувати за допомогою покажчиків.
83
I
Деревом иазивається структура даних, кожнии елемент якої зв'язанин з декількома наступними за ним елементами за допомогою покажчиків.
Схематично дерево, кожнии елемент якого зв'язаний з дво-ма наступними елементами, можна зобразити так (мал. 24):
4
Розглянемо декілька прикладів представления дерев, де елементами є множима літер.
Мал. 25
1. Вкладені множини (мал. 25):
2. Відступи: А В D
і Е
j к L С
F О
G М N
Н Р.
84
3. Вкладені дужки:
(А (В (D (i), EG,k, L)), С (F (О), G (M, N), H (P)))).
3 наведеними прикладами представления дерев ми досить часто маемо справу. Перший приклад - схематичне представ-лення структури деякого підприємства або організації із зоб-раженням підпорядкування різних підрозділів; другий - ієрар-хічна структура систематизованого запису: план твору, зміст книжки, текст Pascal-програми тощо; третій — математичне представления арифметичного виразу.
Наведемо деякі означения дерева як одного із способів представления інформації.
Упорядковане дерево - це дерево, в якого ребра, тобто гілки, що виходять з кожної вершини, упорядковані.
Наприклад, два упорядковані дерева на малюнку 26 різні:
Мал. 26
Вершина у, що знаходиться безпосередньо нижче від вершини х, називається нащадком х. У деревах, зображених на малюнку 26, вершини В і С е нащадками вершини А. Якщо вершина х знаходиться на рівні і, то кажуть, що вершина у знаходиться на рівні і + 1. I навпаки, вершину х називають без-посереднім предком у. Вважається, що корінь дерева (найвища вершина) знаходиться на рівні 0. Максимальний рівень деякої з вершин дерева називається його глыбиною або высотою. Якщо елемент не мае нащадків, то його називають термінальною вершиною, або лыстом, а нетермінальну вершину називають внутрішньою. Кількість безпосередніх нащадків внутрішньої вершини називають її степенем. Максимальний степінь усіх вершин дерева називають степенем дерева. Кількість ребер, які треба пройти від кореня дерева до вершини х, називають довжиною шляху до вершини х. Корінь дерева мае шлях 0, його безпосередш нащадки мають довжину шляху 1 і т. д. Вершина на рівні / мае довжину шляху, рівну і. Довжына шляху всього дерева визначаеться як сума довжин шляхів усіх його ком-понентів. ЇЇ також називають довжиною внутрішнього шляху. Наприклад, довжина внутрішнього шляху для дерева, зобра-женого на малюнку 27, дорівнює 36.
Для дерев існує поняття зовнішнього шляху. Для його визна-чення дерево треба доповнити спеціальними вершинами у тих
місцях, де в заданому дереві відсутні піддерева. Додаткові вершини добавляються за правилом: усі вершини повинні стати максимального степеня, який дорівнює степеню дерева. Розширене дерево матиме такий вигляд (мал. 27):
Мал. 27
Наприклад, довжина зовнішнього шляху на малюнку 27 дорівнює 24.
Особливе місце у структурі даних «дерево» займають упо-рядковані дерева другого степеня. їх ще називають двійкови-ми, або бінарними.
Визначимо упорядковане бінарне дерево як кінцеву мно-жину елементів, тобто вершин, яка або порожня, або скла-дається з кореня з двома окремими двійковими деревами - лі-вим і правим піддеревами.
Приклади бінарних дерев:
— генеалогічне дерево, де, як у кожної людини, в термінах поняття «дерево» «нащадками» є батько та мати;
- арифметичний вираз з бінарними операціями. Наприклад, для арифметичного виразу (а + Ь/с) ■ (d — е ■ f) деревовидна схе ма виглядатиме так (мал. 28):
Мал. 28
Як програмно представити дерево? Кожну вершину можна розглядати як вхід у нове дерево. Це наводить на думку про ви-користання рекурсії в описі дерева. Посилання на порожні дерева, тобто термінальні вершини, будемо позначати значениям nil - порожне посилання.
86
У термінах посилань представимо попереднє дерево так (мал. 29):
£~\
Г~і
г- I -у
*- I ta
nil nil
nil nil
I
I
t Tt t У ▼ t V
nil nil nil nil nil nil nil nil
Мал. 29
Розглянемо бінарне дерево як структуру даних. За анало-гією зі списком опишемо й так:
Type Ptr= "Node; Node = record
data: <тип > ; left, right: Ptr; end;
Отже, тепер можна дати ще одне означения структури даних «дерево».
I
Дерево з базовим типом Т — це порожне дерево або деяка вершина типу Т з кінцевою кількістю зв'язаних із нею ок-ремих дерев з базовим типом Т, що називаються піддере-вами.
А як же в динамічній пам'яті будуть розміщені елементи такого бінарного дерева? З'ясуємо, яким чином структура даних «дерево» відображається на пам'ять комп'ютера. Оскільки пам'ять мае лінійну дискретну структуру, то й елементи роз-ташовуються там один за одним. Лише значення покажчиків указуватимуть на слідування одного елемента за іншим. Опробуемо схематично зобразити розташування в пам'яті комп'ютера структуру дерева, що відповідає арифметичному виразу (а + b/c) -(d-e-f)(мал. 30).
87
*ш
Мал. 30
Далі найкраще розглянути конкретну задачу, в якій вико-ристаємо дерево. Це буде задача формування бшарного дерева для цілих чисел, що читаються з файла. Будемо будувати дерево мінімальної глибини, розміщуючи вершини порівну зліва і справа від кожної вершини. Правило формування такого дерева визначимо так:
-
перше число розмістимо у першій вершині в якості коре-ня дерева;
-
побудуємо ліве піддерево з nl вершинами, де nl = п div 2;
3) побудуємо праве піддерево з пг вершинами, де пг = п — пі — 1. Побудоване за цим правилом дерево називається ідеально
збалансованим, бо кількість вершин у його правих і лівих під-деревах відрізняється не більш як на 1.
Почнемо зі створення дерева. Для цього можна запропонува-ти використання такої рекурсивно! функції:
function tree_balans (n: integer): Ptr; var q: Rr;
x, nl, nr: integer; begin
if n = 0 then q := nil else begin
nl := n div 2; nr := n - nl - 1 read (x); new (q); with q" do begin data := x;
left := tree_balans (nl); right := tree_balans (nr); end; end; tree_balans := q; end;
Використати функцію створення дерева можна такими дво-ма операціями:
read (n);
root := treebalans (n);
88
У результаті змінна root міститиме адресу його кореневого елемента.
Цікаво було б побачити, яким чином елементи збалансова-ного дерева наслідують один одного. Назвемо цю процедуру PrintTree:
procedure PrintTree(t: Ptr; h: integer); var i: integer; begin