Реферат на тему:

Структури даних

Означення. Опис складних об’єктів засобами більш простих типів даних,
які безпосередньо представляються у машині, називається структурами
даних.

Найпоширеними складними об’єктами є множини та послідовності
(впорядковані множини).

Списком називається впорядкована послідовність елементів a1, a2, …,
an. Розмір або довжина цього списку дорівнює n. Список розміру 0
називається порожнім. Список можна реалізувати або за допомогою масиву
або за допомогою зв’язування його елементів вказівниками (зв’язаний
список). У зв’язаному списку елементи лінійно впорядковані, їх порядок
визначається вказівниками, що входять у склад елементів списка. Елемент
двостороннього зв’язаного списка містить три поля: ключ та два
вказівника – наступний та попередній. В односторонньому зв’язаному
списку відсутнє поле ‘попередній’. У впорядкованому списку елементи
розташовані в порядку зростання ключів на відміну від невпорядкованого
списка.

Стеки та черги – це динамічні множини (або спеціальні типи списків), в
яких елемент що додається, визначається структурою множини. Стек працює
за принципом “останній прийшов – перший пішов (LIFO)”, а черга – за
принципом “перший прийшов – перший пішов (FIFO)”.

Нехай PList – вказівник на однозв’язний список.

PList = ^List;

List = object

val: integer; /* значення */

next: PList; /* вказівник на наступний елемент списку */

end;

Стек має наступні методи:

PUSH – покласти елемент до стеку;

POP – взяти верхній елемент зі стеку;

TOP – повернути верхній елемент стеку без його вилучення;

IsEmpty – перевірити, чи є стек порожнім;

PRINT – надрукувати елементи стеку.

Pstack – вказівник на об’єкт стек.

PStack = ^Stack;

Stack = object

lst: PList;

procedure Push (Value: integer);

function Pop :integer;

function Top :integer;

function IsEmpty :boolean;

procedure Print;

end;

procedure Stack.Push (Value:integer);

var temp: PList;

begin

New (temp);

temp^.val := Value;

temp^.next := lst;

lst := temp;

end;

function Stack.Pop: integer;

begin

if (lst = NIL) then Pop := -1 else

begin

Pop := lst^.val;

lst := lst^.next;

end;

end;

function Stack.Top: integer;

begin

Top := lst^.val;

end;

function Stack.IsEmpty: boolean;

begin

if (lst = NIL) then IsEmpty := TRUE

else IsEmpty := FALSE;

end;

procedure Stack.Print;

var tmp: PList;

begin

tmp := lst;

while (tmp <> NIL) do

begin

write(tmp^.val); write(‘ ‘);

tmp := tmp^.next;

end;

writeln;

end;

Орієнтованим графом називається структура G = (V, E), де V – скінченна
множина вершин, E – множина ребер, що задається як бінарне відношення на
V, тобто E ??V ??V. Орієнтований граф називається орграфом. Граф може
містити ребра — цикли, які сполучають вершину саму з собою. Про ребро
(u, v) говорять, що воно виходить із вершини u та входить у вершину v.

В неорієнтованому графі множина ребер E складається із невпорядкованих
пар вершин. Про ребро (u, v) неорієнтованого графу говорять, що воно
інцидентно вершинам u та v. Якщо в графі G є ребро (u, v), то говорять,
що вершина u суміжна з вершиною v. Для неорієнтованого графу відношення
суміжності є симетричним.

Степенем вершини в неорієнтованому графі називається кількість
інцидентних їй ребер. Для орієнтовних графів розрізняють вхідну та
вихідну вершини; сума вхідних та вихідних степеней називається степенем
вершини.

Деревом називається зв’язаний граф без циклів. Дерево являє собою
скінченну множину елементів Т, які називаються вершинами. Якщо множина
вершин Т порожня, то дерево називається порожнім; інакше в дереві
повинна бути виділена одна вершина, яка називається коренем (якщо
виділеної вершини не існує, то така структура називається деревом без
виділеного кореня). Якщо (y, x) є останнім ребром на шляху з кореня до
х, то y називається батьком, а x – сином. Корінь є єдиною вершиною, яка
не має батька. Вершини, які мають одного спільного батька, називаються
братами. Якщо кожна вершина T (батько) сполучається не більше ніж з k
іншими вершинами T1, T2, …, Tk (синами), то таке дерево називається k
— арним. Якщо вершина не має синів, то вона називається листом; інакше
вершина називається внутрішньою. Кількість синів у вершини дерева
називається її степенем. Глибиною вершини називається довжина шляху від
кореня до цієї вершини. Висотою дерева називається найбільша довжина від
кореня до листа. Повним k — арним деревом називається k — арне дерево, в
якому усі листи мають однакову глибину та усі внутрішні вершини мають
однаковий степінь.

Властивість дерев. Нехай G = (V, E) – неорієнтований граф. Тоді наступні
твердження еквівалентні:

G є деревом без виділеного кореня;

для довільних двох вершин G існує єдиний простий шлях, що їх сполучає;

граф G є зв’язним, але не залишається таким при вилученні хоча б одного
ребра;

граф G є зв’язним і |E| = |V| — 1;

граф G є ациклічним і |E| = |V| — 1;

граф G є ациклічним, але додання довільного ребра породжує цикл.

У двійковому дереві кожна вершина може мати не більше двох синів (лівий
та правий сини). Кожна вершина окрім кореня, має батька. При
представленні двійкового дерева за допомогою вказівників кожна вершина
містить ключ Val, вказівники на лівого Left та правого Right синів, а
також на батька Up. Якщо сина або батька (для кореня) не існує, то
відповідний вказівник містить NIL.

Ключі у двійковому дереві містяться у відповідності до властивості
впорядкованості:

Нехай x – довільна вершина двійкового дерева. Якщо вершина y
знаходиться в лівому піддереві вершини x, то x.Val > y.Val. Якщо
вершина y знаходиться в правому піддереві вершини x, то x.Val < y.Val. Нехай PTree – вказівник на структуру типу бінарне дерево. PTree = ^Tree; Tree = object Val: integer; /* значення вершини */ Left: PTree; /* вказівник на лівого сина */ Right: PTree; /* вказівние на правого сина */ Up: PTree; /* вказівник на батька */ end; Об’єкт дерево має наступні методи: INSERT – вставка елемента до дерева; DELETE – вилучення елемента з дерева; FIND – пошук елемента в дереві; FindMin – пошук вузла дерева з мінімальним елементом; FindMax – пошук вузла дерева з максимальним елементом; PrintLR – обхід дерева зліва направо. PTreeStr = ^TreeStr; TreeStr = object TTree: PTree; procedure Insert (Value:integer); procedure Delete (Value:integer); function Find (Value:integer): boolean; function FindMin: PTree; function FindMax: PTree; procedure PrintLR; end; Властивість впорядкованості дозволяє надрукувати всі ключі у неспадному порядку за допомогою обходу дерева зліва направо, який відбувається наступним чином: побувати в лівому піддереві побувати в корені побувати в правому піддереві procedure PLR (Tree: PTree); begin if (Tree = NIL) then Exit; PLR (Tree^.left); write (Tree^.Val, ' '); PLR (Tree^.right); end; procedure TreeStr.PrintLR; begin PLR (TTree); writeln; end; function FindEl (var Tree: PTree; Value:integer):boolean; begin if (Tree = NIL) then FindEl := FALSE else if (Tree^.Val = Value) then FindEl := TRUE else if (Value < Tree^.Val) then FindEl := FindEl (Tree^.Left, Value) else FindEl := FindEl (Tree^.Right, Value); end; function TreeStr.Find (Value:integer):boolean; begin Find := FindEl (TTree, Value); end; Мінімальний (максимальний) ключ в дереві можна знайти, якщо пройти по вказівникам Left (Right) від кореня поки не досягнемо вершини, лівий (правий) син якої дорівнює NIL. Процедура FindMin (FindMax) повертає вказівник на вершину, яка містить мінімальний (максимальний) ключ. Час виконання вказаних процедур дорівнює O(h), де h – висота дерева. function FMax (Tree:PTree):PTree; begin if (Tree^.Right = NIL) then FMax := Tree else FMax:= FMax (Tree^.Right); end; function TreeStr.FindMax:PTree; begin if TTree = NIL then FindMax := NIL else FindMax := FMax (TTree); end; function Fmin (Tree:PTree):PTree; begin if (Tree^.Left = NIL) then FMin := Tree else FMin:= FMin (Tree^.Left); end; function TreeStr.FindMin:PTree; begin if TTree = NIL????????????????????????????? У процедурі вставки Insert елемента Value в бінарне дерево Tree відбувається рух вниз по дереву від корня до листа. В кожній вершині x, яка не є листом, процедура обирає напрямок руху (вліво чи вправо) у відповідності до властивості впорядкованості: якщо Value < x.Val, то відбувається рух вліво, інакше – вправо. Дійшовши до листа z, процедура вставляє нову вершину w, ключ якої дорівнює Value знову ж таки за властивістю впорядкованості: якщо Value < z.Val, то z.Left := w, інакше z.Right := w. Час виконання процедури дорівнює O(h), де h – висота дерева. procedure InsElem (var Tree: Ptree; Value: integer); begin if (Tree = NIL) then begin New (Tree); Tree^.val := Value; Tree^.Left := nil; Tree^.Right := nil; Exit; end; if (Value > Tree^.Val) then

if Tree^.Right = NIL then

begin

New (Tree^.Right);

Tree^.Right^.val := Value;

Tree^.Right^.Left := NIL;

Tree^.Right^.Right := NIL;

Tree^.Right^.Up := Tree;

end

else InsElem (Tree^.Right, Value)

else

if Tree^.Left = NIL then

begin

New (Tree^.Left);

Tree^.Left^.val := Value;

Tree^.Left^.Left := NIL;

Tree^.Left^.Right := NIL;

Tree^.Left^.Up := Tree;

end

else InsElem (Tree^.Left, Value);

end;

procedure TreeStr.Insert (Value:integer);

var Tmp: PTree;

begin

InsElem (TTree, Value);

end;

При видаленні вершини х з бінарного дерева можливі три випадки:

х не має синів – тоді достатньо розташувати NIL у відповідне поле його
батька (замість х);

х має одного сина – тоді його можна вирізати, поєднавши його батька
напряму з цим сином;

х має двох синів – необхідно знайти наступний за х елемент y (який вже
не має лівого сина), скопіювати його ключ та певні дані з вершини y до
вершини x, а саму вершину y видалити вище описаним способом.

procedure DelElem (var Tree: PTree; Value: integer);

var tmp, Repl: PTree;

begin

if (Tree = NIL) then Exit;

if (Value < Tree^.Val) then DelElem (Tree^.Left, Value) else if (Value > Tree^.Val) then DelElem (Tree^.Right, Value)

else if ((Tree^.Left <> NIL) and (Tree^.Right <> NIL)) then

begin

Repl := Fmin (Tree^.Right);

Tree^.Val := Repl^.Val;

DelElem (Tree^.Right, Repl^.Val);

end

else

begin

tmp := Tree;

if (Tree^.Left = NIL)
then???????????††????????????????????????††????????†????????????????????
??????????????????†???????????????

Дерева з довільним розгалудженням можна перетворити у двійкове дерево за
принципом “ліва дитина – правий сусід”. Кожна вершина містить три
вказівники:

вказівник p на батька;

вказівник left-child[x] на саму ліву дитину вершини х;

вказівник right-child[x] на найближчого сусіда вершини х;

Вершина х не має дітей тоді і тільки тоді коли left-child[x] = NIL.
Вершина х є крайньою правою дитиною свого батька якщо right-child[x] =
NIL.

AVL — деревом (Adelson-Velskii and Landis) називається бінарне дерево,
яке має наступні властивості:

висоти піддерев кожного батька відрізняються не більше ніж на 1:

кожне піддерево батька є AVL — деревом.

AVL — дерева належать до класу збалансованих бінарних дерев.

Ліве дерево є AVL — деревом, оскільки у нього висота кожного лівого сина
на 1 більша за висоту відповідного правого сина. Дерево, яке зображене
справа, не є AVL — деревом, оскільки лівий син вершини 12 (дерево з
коренем 8) має висоту 4, а правий син вершини 12 (дерево з коренем 18)
має висоту 2.

Дерево відрізків – це структура даних, яка створена для роботи з такими
інтервалами на числовій осі, кінці яких належать фіксованій множині з N
абсцис (далі цими абсцисами будемо вважати цілі числа в інтервалі [1,
N]). Оскільки множина абсцис фіксована, то дерево відрізків являє собою
статичну структуру по відношенню до цих абсцис.

Дерево відрізків – це двійкове дерево з коренем. Для заданих цілих чисел
l та r (l < r) дерево відрізків T(l, r) будується рекурсивно наступним чином: воно складається з кореня v з параметрами B[v] = l, E[v] = r (B – Begin, E - End). Якщо r - l > 1, то воно складається з лівого піддерева
T(l, [(B[v] + E[v])/2]) та правого піддерева T([(B[v] + E[v])/2], r).

Інтервали, що належать множині {[B[v], E[v]]: v — вузел T(l, r)},
називаються стандартними інтервалами дерева T(l, r). Стандартні
інтервали, які належать листам T(l, r), називаються елементарними
інтервалами. T(l, r) збалансоване та має глибину ?log2(r — l)?.

Дерево відрізків призначено для динамічного запам’ятання інтервалів,
кінці яких належать множині {l, l + 1, …, r}. Якщо r — l > 3, то
інтервал [b, e] з цілими b < e буде розбито в набір не більш ніж ?log2 (r - l)? + ?log2 (r - l)? - 2 стандартних інтервалів дерева T(l, r). Функція BuildTree ( l, r ) будує та повертає дерево відрізків T(l, r). Складний тип даних tree має структуру дерева, в якій left та right – вказівники на лівого та правого сина, begin та end – параметри вершини. BuildTree ( l, r ) temp ? new tree; begin [temp] ? l; end [temp] ? r; if (r - l < 2) then begin left[temp] ? NIL; right[temp] ? NIL; return temp; end; left[temp] ? BuildTree ( l, [(l + r) / 2] ); right[temp] ? BuildTree ( [(l + r) / 2], r ); return temp; Фрагментація інтервала [b, e] повністю визначається операцією занесення [b, e] в дерево відрізків Т. До структури даних tree додамо булевий параметр flag, який буде відповідати за включення стандартного інтервалу до інтервалу [b, e]. Тобто якщо для деякої вершини v має місце flag[v] = TRUE, то [ begin[v], end[v] ] ? [b, e]. InsertTree ( b, e, T ) if (b ??begin[T] and end[T] ??e) then flag[T] = TRUE; else begin if (b 2

15

5

24

20

35

2

1

3

30

47

Малюнок Х. Пошук вершини з мінімальним та

максимальним ключем у бінарному дереві

MAX

MIN

15

5

24

20

35

2

1

3

30

47

Малюнок Х.

Вставка вершини 30 у бінарне дерево

30 > 15

30 > 24

30 < 35 Малюнок Х. Вилучення вершини 24 з бінарного дерева 15 5 30 20 35 2 1 3 47 30 15 5 24 20 35 2 1 3 30 47 FMin (24.Right) = 30, Delete (24.Right, 30) ROOT Малюнок Х. Перетворення дерева з довільним розгалудженням у бінарне Малюнок Х. Структура AVL - дерева 4,15 4, 9 9,15 4, 6 6, 9 9,12 12,15 4, 5 5, 6 6, 7 7, 9 9,10 10,12 12,13 13,15 7, 8 8, 9 10,11 11,12 13,14 14,15 Малюнок Х. Дерево відрізків T(4, 15) 2; 4 1; 2 3; 4 5; 6 2 1 3 4 5 6 Малюнок Х. 2 - 3 дерево v2 f4 e5 f2 f1 e2 e1 v4 e6 e4 f3 v3 e3 v1 3 2 1 4 5 a2 a10 a3 a1 a9 a8 a4 1 a7 a5 a6 7 6 4 2 3 5 Малюнок Х. Планарний граф a b c x y a b c x y Малюнок Х. Операція UNION над двома неперитинаючими множинами

Похожие записи