Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции_Паскал.doc
Скачиваний:
2
Добавлен:
21.09.2019
Размер:
1.21 Mб
Скачать

Дерева і пошук у деревах

Д еревами називаються структури даних наступного виду:

Елементи дерева називаються вершинами. Вершина Tree^ називається коренем дерева, а вся множина вершин, зв'язаних з деякою вершиною за допомогою одного з покажчиків називається піддеревом. Вершини, у яких усі покажчики рівні nil, іноді називають листами.

Докладніше ми розглянемо варіант двійкового дерева, тобто такого, у якому кожна вершина має два піддерева (кожне з них може бути порожнім). Такі дерева виявляються дуже зручними для рішення задачі пошуку, коли ключі для наших даних (наприклад прізвища при пошуку телефонних номерів) можна порівнювати на "=", "<" і ">". У кожну вершину дерева заноситься елемент даних, причому робиться це таким чином, щоб для будь-якої вершини всі ключі даних (чи самі дані в найпростішому випадку) з лівого піддерева були менші ключа цієї вершини, а всі ключі з правого — більші. Виконання такої вимоги можна досягти при послідовному додаванні елементів (тобто побудові дерева, починаючи з «нуля», точніше з nil).

При описаній побудові дерева пошук виявляється досить простою справою: спочатку ми порівнюємо шуканий ключ із ключем кореня дерева. Якщо ці два ключі збігаються, то елемент знайдений, у противному випадку виконуємо пошук у левом піддереві, інакше — у правом, далі в обраному піддереві знову виконуємо порівняння його кореня із шуканим ключем, і т.д. Цей процес закінчиться або коли ми знайшли ключ, або коли чергове піддерево виявилося порожнім (це означає, що такий ключ у дереві відсутній).

Для реалізації двійкового дерева спочатку розглянемо його опис на Паскалі:

type tNodePtr = ^tNode; {покажчик на вершину}

tNode = record

data: tMyData;

left,right: tNodePtr;

end;

tTree = tNodePtr; {для доступу до дерева досить зберігати покажчик на його корінь}

Під даними (tMyData) будемо розуміти запис, що складається з ключа, необхідного для порівнянь, і власне даних:

type tMyData = record

key: tKey;

data: tData;

end;

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

Додавання елемента є рекурсивною процедурою:

procedure InsertNode(t: tTree; key: tKey; data: tData);

begin

if t=nil then begin

new(t);

t^.key:=key;

t^.data:=data;

end

else if key<t^.key then InsertNode(t^.left,key,data)

else InsertNode(t^.right,key,data);

end;

Після того як дерево побудоване, можна виконувати пошук (також рекурсивний):

function Search(t: tree; key: tKey; var data: tData): boolean;

{повертає значення знайдене / не знайдений}

begin

if t=nil then Search:=false

else if key = t^.key then begin

data:=t^.data;

Search:=true;

end

else if key<t^.key then Search:=Search(t^.left,key,data)

else Search:=Search(t^.right,key,data);

end;

Легко помітити, що елементи даних, «покладені» у двійкове дерево можна виводити у відсортованому порядку:

procedure Traversal(t: tTree); {обхід дерева}

begin

if t<>nil then begin

Traversal(t^.left);

writeln('Key:',t^.key,' Data:',t^.data);

Traversal(t^.right);

end;

end;

Таблиці і найпростіші алгоритми пошуку.