Ëåêöèÿ 14

Äåðåâüÿ.

Äåðåâî — ýòî àáñòðàêòíàÿ ñòðóêòóðà äàííûõ, èåðàðõèÿ êîòîðîé ïîõîæà íà äåðåâî. Ñîñòîèò èç ñâÿçàííûõ óçëîâ, îäèí èç êîòîðûõ ÿâëÿåòñÿ «êîðíåì». Êàæäûé óçåë ìîæåò èìåòü îäíîãî ïðåäêà è/èëè îäíîãî èëè íåñêîëüêèõ ïîòîìêîâ. (Äåðåâî ÿâëÿåòñÿ ñâÿçíûì ãðàôîì áåç öèêëîâ.)

Êîðåíü äåðåâà — ýòî ñàìûé âåðõíèé óçåë.

Äåðåâî ìîæíî îïðåäåëèòü ðåêóðñèâíî êàê ìíîæåñòâî óçëîâ, îäèí èç êîòîðûõ ÿâëÿåòñÿ êîðíåì, ïðè ýòîì êàæäûé óçåë ÿâëÿåòñÿ ñòðóêòóðîé äàííûõ, ñîäåðæàùåé íåêîå çíà÷åíèå, à òàêæå ññûëêè íà äðóãèå (äî÷åðíèå åìó) óçëû, ïðè óñëîâèè, ÷òî íà êîðíåâîé óçåë ññûëêè íåò, à íà îñòàëüíûå óçëû èìååòñÿ ðîâíî ïî îäíîé ññûëêå.

Ëèñò — óçåë, íå èìåþùèé äî÷åðíèõ ýëåìåíòîâ (ïîòîìêîâ).

Âíóòðåííèé óçåë — óçåë äåðåâà, èìåþùèé ïîòîìêîâ.

Ãëóáèíà äåðåâà — ñàìûé äëèííûé ïóòü îò êîðíÿ äåðåâà äî åãî ëèñòà.

Äåðåâî, â êîòîðîì êàæäûé óçåë èìååò íå áîëåå äâóõ ïîòîìêîâ, íàçûâàåòñÿ äâîè÷íûì äåðåâîì.

Îáõîä óçëîâ äåðåâà


16 → 11 →10 → 1, 2; 5 → 4; 9 → 6, 8

Îáõîä äåðåâà «â ãëóáèíó»: îáõîä âñåõ ïîòîìêîâ êàæäîãî óçëà. Óäîáíî ðåàëèçîâûâàòü ðåêóðñèâíî:

Ïðîöåäóðà Îáõîä äåðåâà â ãëóáèíó

Îáõîä ïîääåðåâà â ãëóáèíó <âõ: äåðåâî.root>

Êîíåö ïðîöåäóðû

Ïðîöåäóðà Îáõîä ïîääåðåâà â ãëóáèíó <âõ: node: óçåë äåðåâà>

Îáðàáîòàòü óçåë<âõ: node>

Öèêë äëÿ êàæäîãî óçëà child èç node.childs âûïîëíÿòü

Îáõîä ïîääåðåâà â ãëóáèíó <âõ: child>

Êîíåö öèêëà

Êîíåö ïðîöåäóðû



16 → 11 → 9 → 10 → 5 → 6 → 8 → 1 → 2 → 4


Îáõîä äåðåâà «â øèðèíó»: îáõîä ïîñëåäîâàòåëüíî óçëîâ îäíîãî óðîâíÿ, ïåðåõîäÿ ïîñëåäîâàòåëüíî îò âåðõíèõ óðîâíåé ê íèæíèì. Ïîðÿäîê ïîñåùåíèÿ óçëîâ óäîáíî îðãàíèçîâàòü ïðè ïîìîùè î÷åðåäè

Ïðîöåäóðà Îáõîä äåðåâà â øèðèíó

Î÷åðåäü_óçëîâ.ñäåëàòü ïóñòîé

Î÷åðåäü_óçëîâ.äîáàâèòü<âõ: äåðåâî.root>

Öèêë ïîêà Î÷åðåäü_óçëîâ.íåïóñòà âûïîëíÿòü

Î÷åðåäü_óçëîâ.âçÿòü ýëåìåíò èç î÷åðåäè â <âûõ: node>

Îáðàáîòàòü óçåë<âõ: node>

Öèêë äëÿ êàæäîãî óçëà child èç node.childs âûïîëíÿòü

Î÷åðåäü_óçëîâ.äîáàâèòü ýëåìåíò â êîíåö î÷åðåäè <âõ: child>

Êîíåö öèêëà

Êîíåö öèêëà

Êîíåö ïðîöåäóðû

Äâîè÷íàÿ êó÷à

Äâîè÷íàÿ êó÷à (ïèðàìèäà, ñîðòèðóþùåå äåðåâî) — ýòî äâîè÷íîå äåðåâî, óäîâëåòâîðÿþùåå ñëåäóþùèì óñëîâèÿì:

1) Çíà÷åíèå â êàæäîì óçëå äåðåâà íå ìåíüøå, ÷åì çíà÷åíèå â ëþáîì èç ïîòîìêîâ ýòîãî óçëà;

2) Êàæäûé ëèñò èìååò ãëóáèíó d èëè d-1, ãäå d – ãëóáèíà äåðåâà;

3) Ñàìûé ãëóáîêèé ñëîé çàïîëíÿåòñÿ áåç ïðîïóñêîâ.

Çíà÷åíèÿ, ñîäåðæàùèåñÿ â óçëàõ äâîè÷íîé êó÷è, óäîáíî õðàíèòü â ìàññèâå ïîñëîéíî, íà÷èíàÿ ñâåðõó äåðåâà. Êîðåíü äåðåâà õðàíèòñÿ â Array[0], åãî ëåâûé ïîòîìîê â Array[1], ïðàâûé â Array[2] è ò. ä. Ïîòîìêè ýëåìåíòà Array[i] íàõîäÿòñÿ â Array[2*i+1] è Array[2*i+2].

Ïðè íóìåðàöèè ñ íóëÿ ñëîåâ äåðåâà ñâåðõó âíèç è óçëîâ ñëîÿ ñëåâà íàïðàâî, i-é óçåë â j-ì ñëîå õðàíèòñÿ â ýëåìåíòå âåêòîðà ñ èíäåêñîì i+2j-1 (ïðè èíäåêñàöèè ýëåìåíòîâ âåêòîðà, íà÷èíàÿ ñ 0).

Ïðèìåð 1. Ñëåäóþùèé ìàññèâ õðàíèò ñîäåðæèìîå ïðèâåäåííîé íà ðèñóíêå äâîè÷íîé êó÷è:

16

11

9

10

5

6

8

1

2

4













Âîïðîñ. Êàê ïî èíäåêñó â ìàññèâå âû÷èñëèòü äëÿ ýëåìåíòà íîìåð óðîâíÿ â äåðåâå è åãî íîìåð â óðîâíå?

N → L, n

3(10) → 2,

L = [log2(N + 1)], n = N – (2L - 1)


Èíäåêñ 9 (ýëåìåíò 4) → L=3, n = 2


Âîïðîñ. Êàê ïî íîìåðó óðîâíÿ â äåðåâå è åãî íîìåðó â óðîâíå âû÷èñëèòü èíäåêñ â ìàññèâå ?

L, n → N = 2L – 1 + n

Ýëåìåíò 4: L=3, n=2 => N = 9


Âîïðîñ. Êàê ìàññèâ ïðåâðàòèòü â äâîè÷íóþ êó÷ó?

0

1

2

3

4

5

6

7

8

9

10

11

4

10

-7

3

12

16

-10

4

5

1

-2

0






Ëþáîé ìàññèâ ìîæíî ïðåäñòàâèòü â âèäå äâîè÷íîãî äåðåâà, óäîâëåòâîðÿþùåãî ñâîéñòâàì 2) è 3). Îñòàåòñÿ òîëüêî ïåðåìåñòèòü çíà÷åíèÿ ýëåìåíòîâ âíóòðè ìàññèâà òàê, ÷òîáû îíè óäîâëåòâîðÿëè ñâîéñòâó 1).

Áóäåì èñïîëüçîâàòü èòåðàòèâíûé ìåòîä, èäÿ ñíèçó äåðåâà ââåðõ, ïðîõîäÿ ïî âñåì âíóòðåííèì óçëàì (òî åñòü óçëàì, íå ÿâëÿþùèìèñÿ ëèñòüÿìè) ñïðàâà íàëåâî, ïðåâðàùàÿ êàæäîå äåðåâî ñ êîðíåì â òåêóùåì óçëå â äâîè÷íóþ êó÷ó.

Ïðè òàêîì ïîðÿäêå îáõîäà ó êàæäîãî òåêóùåãî óçëà îáà ïîääåðåâà áóäóò óæå îáîéäåíû, òî åñòü ïðåâðàùåíû â äâîè÷íóþ êó÷ó. Íàì îñòàåòñÿ òîëüêî îáúåäèíèòü èõ ñ òåêóùèì óçëîì òàê, ÷òîáû ðåçóëüòàò áûë òîæå äâîè÷íîé êó÷åé.

Ñëåäóþùàÿ ïðîöåäóðà (heapify) ðåàëèçóåò îïèñàííûé àëãîðèòì:

Ïðîöåäóðà heapify<âõ: ar: ìàññèâ, N: öåëîå ÷èñëî>

! Äàíî: ìàññèâ ar, N – ðàçìåð ìàññèâà

! Íàäî: ìàññèâ ar ñîäåðæèò äâîè÷íóþ êó÷ó ðàçìåðà N

! Àëãîðèòì: ïðåâðàùàåì «õâîñò» ìàññèâà â äâîè÷íóþ êó÷ó,

! ïîñëåäîâàòåëüíî ñäâèãàÿ íà÷àëî «õâîñòà» ê íà÷àëó ìàññèâà

start := parent(N-1) ! start := èíäåêñ ñàìîãî ïîñëåäíåãî âíóòðåííåãî óçëà

Öèêë ïîêà start >= 0 âûïîëíÿòü

siftDown(ar, start, N-1) ! Ïðîñåÿòü: åñëè íàäî, ïåðåìåñòèòü ñîäåðæèìîå

! êîðíÿ âíèç, ÷òîáû äåðåâî ñòàëî äâîè÷íîé êó÷åé

start = start – 1 ! Ïåðåõîäèì ê ïðåäûäóùåìó âíóòðåííåìó óçëó

Êîíåö öèêëà

Êîíåö ïðîöåäóðû

Ïðîöåäóðà parent<âõ: n: èíäåêñ óçëà â ìàññèâå>

! Âîçâðàùàåò èíäåêñ ðîäèòåëüñêîãî óçëà

îòâåò := (n – 1) / 2

Êîíåö ïðîöåäóðû


Ïðîöåäóðà siftDown îñíîâûâàåòñÿ íà òîì, ÷òî îáà äî÷åðíèõ ïîääåðåâà íåêîåãî óçëà óæå ÿâëÿþòñÿ äâîè÷íûìè êó÷àìè, è òåïåðü íàäî âñå äåðåâî ñ êîðíåì â ýòîì óçëå ñäåëàòü äâîè÷íîé êó÷åé. Åñëè çíà÷åíèå V â ðàññìàòðèâàåìîì óçëå áîëüøå çíà÷åíèé â îáîèõ åãî äî÷åðíèõ óçëàõ — âñå â ïîðÿäêå, ïî îïðåäåëåíèþ äåðåâî óæå ÿâëÿåòñÿ äâîè÷íîé êó÷åé.

 ïðîòèâíîì ñëó÷àå íàì ïðèäåòñÿ ïåðåìåñòèòü V âíèç ïî äåðåâó. Ïåðåìåùåíèå ïðîèñõîäèò ïîñðåäñòâîì îáìåíà çíà÷åíèÿìè äâóõ óçëîâ — ðîäèòåëüñêîãî è äî÷åðíåãî (òîãî èç äî÷åðíèõ, â êîòîðîì áÎëüøåå çíà÷åíèå): áîëüøåå çíà÷åíèå èäåò ââåðõ, ìåíüøåå âíèç. Ïðîöåññ íàïîìèíàåò ñîðòèðîâêó «ïóçûðüêîì», òîëüêî çäåñü «ïóçûðåê» ïðîõîäèò íå ïî âñåìó ìàññèâó, à òîëüêî ïî îäíîé âåòâè äåðåâà, ÷òî ñóùåñòâåííî ñîêðàùàåò åãî ïóòü: c O(N) äî O(log N).

Èòàê, åñëè V îêàçàëîñü ìåíüøå, ÷åì çíà÷åíèå â äî÷åðíåì óçëå, ìû îáìåíèâàåì çíà÷åíèå V ñ íàèáîëüøèì èç çíà÷åíèé, íàõîäÿùèõñÿ â äâóõ åãî äî÷åðíèõ óçëàõ. Ýòó æå ïðîöåäóðó ïðîâîäèì ñíîâà ñ òåì óçëîì, êóäà ïåðåìåñòèëîñü V è òàê äàëåå.


Ïðîöåäóðà siftDown<âõ: ar: ìàññèâ, root: èíäåêñ, end: èíäåêñ>

! Ïî÷èíèòü êó÷ó, êîðåíü êîòîðîé íàõîäèòñÿ â ýëåìåíòå ñ èíäåêñîì root,

! ïðåäïîëàãàÿ, ÷òî îáà äî÷åðíèõ ïîääåðåâà ÿâëÿþòñÿ äâîè÷íûìè êó÷àìè

! end – èíäåêñ ïîñëåäíåãî óçëà äåðåâà

! Ïîêà ó êîðíÿ åñòü äî÷åðíèé óçåë ñî çíà÷åíèåì áîëüøèì, ÷åì çíà÷åíèå â êîðíå

Öèêë ïîêà ((leftChild(root) <= end) è (ar[root] < ar[leftChild(root))) èëè

((rightChild(root) <= end) è (ar[root] < ar[rightChild(root)))) âûïîëíÿòü

! Åñëè çíà÷åíèå â ëåâîì äî÷åðíåì óçëå áîëüøå, ÷åì â ïðàâîì

Åñëè (rightChild(root) > end) èëè (ar[leftChild(root)] > ar[rightChild(root)]) òî

swap(root, leftChild(root)) ! Îáìåíèâàåì çíà÷åíèÿ êîðíÿ è ëåâîãî äî÷åðíåãî óçëà

root := leftChild(root)

针֌

swap(root, rightChild(root)) ! Îáìåíèâàåì çíà÷åíèÿ êîðíÿ è ïðàâîãî äî÷åðíåãî óçëà

root := rightChild(root)

Êîíåö åñëè

Êîíåö öèêëà

Êîíåö ïðîöåäóðû

Ïðîöåäóðà leftChild<âõ: n: èíäåêñ óçëà â ìàññèâå>

! Âîçâðàùàåò èíäåêñ ëåâîãî äî÷åðíåãî óçëà

îòâåò := n * 2 + 1

Êîíåö ïðîöåäóðû

Ïðîöåäóðà rightChild<âõ: n: èíäåêñ óçëà â ìàññèâå>

! Âîçâðàùàåò èíäåêñ ïðàâîãî äî÷åðíåãî óçëà

îòâåò := n * 2 + 2

Êîíåö ïðîöåäóðû