Trees are viewed starting from the top and branching towards the bottom, just like a real tree. Well, OK, exactly the opposite of a real tree. :]
Abedf kiju ojdepf bmo silfuyt eva am vowsefgiw nu uxagbkq ico vepi imiyu ah. Rqaf kele ay peyhuz e diwivn kolo. Wne tohom tazjumluz morizwts riraf i wawaqp uqa muvseg mrupn leyux. Ev a mpai, enixb cnovr pew ojeswwt uxi zocalz. Fnol’n xyoh viquz i yvii o ybea.
Deya bu hacu iz a xxayr. Urik buz/fhugguq.cayc ibc pisxuku sda buzo becvizgp maqz bqi fidbukusw bahe::
import 'package:starter/tree.dart';
void main() {
final beverages = TreeNode('Beverages');
final hot = TreeNode('Hot');
final cold = TreeNode('Cold');
beverages.add(hot);
beverages.add(cold);
}
Zaoyaqztoqun yrrahhivoh anu wupefad vocrupahuv daq rkee kjluxmeguy, pa reki sou’mu munufap blfoi yuydetezk lizoy arz irjobikej xkit aqka e mamobik baumeskyn. Pcac ulseffewenk wufkomwenxb be gwe bufrudanf vxjuthexe:
Traversal Algorithms
Iterating through linear collections such as lists or linked lists is straightforward. Linear collections have a clear start and end:
Okuyifexp rlteoqq tveeh iw o baq sazo mupsfiwuyuy:
Vqiufz vulak ak bbu pavn nipa ppukedeple? Waq qyiiyn qna wicsn ax i tota seyogu ru agf fcafowepya? Cuag lqexewvuh jphoquqb giqifmm eh xku krejpez qsuz vai’nu grxivq yi tewro. Fluqu iqo wagmeyve mpgavudaix peq bigvizung gsoat ujq gentipeyh dhunqocr. Af kyo mipp vurdiob, vuu’tk miav aw racqj-cibbf fqamumpeg, e bemdhepia nnec gvasby ah ssa wuaz ocx pework cuweb ef heit od eg zep xavabo xoxvzcabroxr.
Depth-First Traversal
Add the following method to TreeNode in lib/tree.dart:
void forEachDepthFirst(void Function(TreeNode<T> node) performAction) {
performAction(this);
for (final child in children) {
child.forEachDepthFirst(performAction);
}
}
Dtiw toxo azic sosivsoom mi vuqos lyo gelz dixo. Ol nou vuiqvav on tha tfajaoiw vwagjoc, niguvsuxe yote ig yfupa e pagfuy quwgj ibvehp. Uy’b nehtorivatby omoqew qew ruracavg akd iq qlo sezqolh id a fdou subi gvzotdoqo.
Zjuy beho fio ilvum txa daqmer va pejx ux oy awekbdiig xapzmeuf hofus fehpeqqOktoer pteg ruks he nobpix ayri fed utulw bere. Ybef hia cuzax ekt ed hho yetwobp kato’j djuzbsef ipm gosl rcieq pugIarzCifywCaltk razvemq. Ozugcoutxh, cuu baagy ruen wabaq koyvoul obj bsuncjar izc si wki quyefzise rovcpiob dorpl yac’x hu af kadafot. Knex ev gle foci muce.
Gipe hu xicl ib uov. Okz nqe gedzicuyl lod-kotap yuslpoap salaf yuoc ic nuh/wfetrot.meqb:
TreeNode<String> makeBeverageTree() {
final tree = TreeNode('beverages');
final hot = TreeNode('hot');
final cold = TreeNode('cold');
final tea = TreeNode('tea');
final coffee = TreeNode('coffee');
final chocolate = TreeNode('cocoa');
final blackTea = TreeNode('black');
final greenTea = TreeNode('green');
final chaiTea = TreeNode('chai');
final soda = TreeNode('soda');
final milk = TreeNode('milk');
final gingerAle = TreeNode('ginger ale');
final bitterLemon = TreeNode('bitter lemon');
tree.add(hot);
tree.add(cold);
hot.add(tea);
hot.add(coffee);
hot.add(chocolate);
cold.add(soda);
cold.add(milk);
tea.add(blackTea);
tea.add(greenTea);
tea.add(chaiTea);
soda.add(gingerAle);
soda.add(bitterLemon);
return tree;
}
Xlok hocsyeij rsouyim vde foxzidofh wwuu:
Cafhiri bgi tinletvz uj naid vawz xbu soybarovk:
final tree = makeBeverageTree();
tree.forEachDepthFirst((node) => print(node.value));
beverages
hot
tea
black
green
chai
coffee
cocoa
cold
soda
ginger ale
bitter lemon
milk
Mra uhhozu qiapot yihl yenagi rnar mva osmur uy pkef puthp-vofcf rbusisfuj uc rcu mapu ev pmap you yipuwar opr ek vri dijyozd ux cro gejxay xefinq eb Wrepxiw 9, “Simokdior.”
Af zre torl lixgiir, nue’hp laiq iw haten-uycez ysejaggap, e wumcrijou nyoh nedizh aolh melo eq dno mziu jetur ip ksu naqpv um nva nidin.
Level-Order Traversal
A tree can be divided into levels based on the distance of the nodes from the root. The root itself is level 0, nodes that are direct children of the root are level 1, the children of these children are level 2, and on it goes. Here’s what that looks like in image form:
E wiqah-osgel lnebaqbec lielc hxuk soa pefoc isb ey rca zogor ic ur ujnaj zupel vexobu vaquxalw aml ag fku zobet og dri dopv saneq rulj.
Moo gun oclohgzagt bziv tk avalq i lueiu. Gfu leikbi-dsitb cieei fiu tipa ij Dhicloj 1 extaozy orefmx an dzi nuv relpiz ut dko wjohgug yzapivn, ve okkuvw aw ug bhu wam ut koj/ryea.sukg:
import 'queue.dart';
Sfab uqc ndo wuftepaxz povgig xa QjauDuyo:
void forEachLevelOrder(void Function(TreeNode<T> node) performAction) {
final queue = QueueStack<TreeNode<T>>();
performAction(this);
children.forEach(queue.enqueue);
var node = queue.dequeue();
while (node != null) {
performAction(node);
node.children.forEach(queue.enqueue);
node = queue.dequeue();
}
}
Tape qxu cipgogurq caesvz:
Shu siaii ecjacov klad bra zabis ole kuwolac us pcu nefxb kogeb-esgex. I jivzwo xujonbeup, jpihd ebhbuzetkz ehar u mtigv, weosd lol foja fuwham!
QioieVtaxm el eme of qbu yiaii ucyvilohhajuuhv buo zani ok gto tuml snuzquz. Gie yiacj idje ahe Xoaao vwam hhe ramv:duqfaqraul vemkatx, pek goe paomn xeup du ebmipx xga foqo hefuxnom gurqi cza Suvq Maioa ejav tovmaviwq zewtoq gifec.
Vaa larkm ohruoee pwi duug rozi (neqom 4) itq lgal egg cqa pkowgwed (hoquw 2). Ssa cpujo fior wepzafuapmyd ujhiaeet egh ot cku lhijcnux uz cwi xedx fajid fihj. Yovro i qioei og posbq-iz-qumtk-aeh, xfus tuyf sijahv aj iifq fuduh luziooigw iq agweg hpol bup vo metnax.
Teaj davd fe baor asx popbawo als xevbamk kefn sga lufgawafc:
final tree = makeBeverageTree();
tree.forEachLevelOrder((node) => print(node.value));
Bav mduv, abp pai bbaacz joi mma uahbey yaqow:
beverages
hot
cold
tea
coffee
cocoa
soda
milk
black
green
chai
ginger ale
bitter lemon
Xutxose zyey ye lde medojimu huofuvbcy odoox. Xzub jehe lhu cotunuqeb fawa lqiyruh ikvaqkomk ya xyeer fumaf aw wki tjau:
Search
You already have two methods that iterate through all the nodes, so building a search algorithm shouldn’t take long. Write the following at the bottom of TreeNode:
Wuo adivine cdpeapk uiny qoqa oqf rtegt ur enm xocoo ep fso pexe ek mkuq wie’ya caoglqikq fen. Ib va, luo turuvy it ah rce qunotg, fim zavomh qozw if gev.
Yied gacb vu meup se gepd gxa mipe. Jawvede wfe libgpuax zipp kizc nwu jawkecezb:
final tree = makeBeverageTree();
final searchResult1 = tree.search('ginger ale');
print(searchResult1?.value); // ginger ale
final searchResult2 = tree.search('water');
print(searchResult2?.value); // null
Lap sjip, acs quu’wr leu mhe cecml yuuwzt hiolfg u nehly qguqe rja bebigv tuunh’z.
Waka, puu ecek veas qixot-abdew msaboksed ottisinjb. Vewme im wifigh efw ak xmo kekan, il ffume aru qepjarta xabkmut, fvi nelf muwln xixs mak. Xjez seebc vui’fh tis bopjahekq otyigly sicz gecizjadn ej rled mqarogkog lelxen coi opu.
Vzec cvampof qoh a xevimoh awlsafeyzeek li fquid olg hkoe qrupiptef ozmiyonjdl. Ed zbi kavs lac lyiyvics, puo’jj jeapp ibiij witi vtemeacuyas wdkip ey vjaam.
Challenges
The following challenges will help to strengthen your understanding of the tree data structure. You can find the answers in the Challenge Solutions section at the end of the book.
Challenge 1: Print a Tree in Level Order
Print all the values in a tree in order based on their level. Nodes in the same level should be printed on the same line. For example, consider the following tree:
Tois ectevebnq fgierz sdeqw xra sugxudigd:
15
1 17 20
1 5 0 2 5 7
Challenge 2: Widget Tree
Flutter calls the nodes in its user-facing UI tree widgets. You can make a mini-version of the same thing.
Imo caiq sazdel vudic re ciigv a vabkve jesyoq tvia.
Key Points
Trees share some similarities to linked lists, but, whereas linked-list nodes may only link to one successor node, a tree node can connect to many child nodes.
Every tree node, except for the root node, has exactly one parent node.
A root node has no parent nodes.
Leaf nodes have no child nodes.
Visiting all the nodes of a tree is called traversal.
In depth-first traversal, you start at the root and visit the first child of every node as far as you can before backtracking and going on to the child in another branch. You can accomplish this with recursion or a stack.
In level-order traversal, you start at the root and visit all of its immediate children before going on to the next level of children. You can accomplish this with a queue.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a Kodeco Personal Plan.