Äåðåâî — ýòî àáñòðàêòíàÿ ñòðóêòóðà äàííûõ, èåðàðõèÿ êîòîðîé ïîõîæà íà äåðåâî. Ñîñòîèò èç ñâÿçàííûõ óçëîâ, îäèí èç êîòîðûõ ÿâëÿåòñÿ «êîðíåì». Êàæäûé óçåë ìîæåò èìåòü îäíîãî ïðåäêà è/èëè îäíîãî èëè íåñêîëüêèõ ïîòîìêîâ. (Äåðåâî ÿâëÿåòñÿ ñâÿçíûì ãðàôîì áåç öèêëîâ.)
Êîðåíü äåðåâà — ýòî ñàìûé âåðõíèé óçåë.
Äåðåâî ìîæíî îïðåäåëèòü ðåêóðñèâíî êàê ìíîæåñòâî óçëîâ, îäèí èç êîòîðûõ ÿâëÿåòñÿ êîðíåì, ïðè ýòîì êàæäûé óçåë ÿâëÿåòñÿ ñòðóêòóðîé äàííûõ, ñîäåðæàùåé íåêîå çíà÷åíèå, à òàêæå ññûëêè íà äðóãèå (äî÷åðíèå åìó) óçëû, ïðè óñëîâèè, ÷òî íà êîðíåâîé óçåë ññûëêè íåò, à íà îñòàëüíûå óçëû èìååòñÿ ðîâíî ïî îäíîé ññûëêå.
Ëèñò — óçåë, íå èìåþùèé äî÷åðíèõ ýëåìåíòîâ (ïîòîìêîâ).
Âíóòðåííèé óçåë — óçåë äåðåâà, èìåþùèé ïîòîìêîâ.
Ãëóáèíà äåðåâà — ñàìûé äëèííûé ïóòü îò êîðíÿ äåðåâà äî åãî ëèñòà.
Äåðåâî, â êîòîðîì êàæäûé óçåë èìååò íå áîëåå äâóõ ïîòîìêîâ, íàçûâàåòñÿ äâîè÷íûì äåðåâîì.
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
Êîíåö ïðîöåäóðû