Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning 1 Bakgrund och motivation 2 Mål 3 Terminologi och definitioner 4 Binära träd 5 Trädalgoritmer 6 Implementation 7 Sammanfattning Träd Lars Larsson VT 2007 Lars Larsson Träd 1 Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Lars Larsson Träd Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Träd är en datastruktur som används mycket flitigt inom alla möjliga områden av datavetenskapen: Målet med denna föreläsning är att studenterna skall: kunna samtlig viktig terminologi gällande datastrukturen träd, artificiell intelligens, syntaxträd som testar om kod är skriven på rätt sätt, vara speciellt insatta i binära träds egenskaper och konstruktion, snabb inmatning av text via mobiltelefoner (T9), kunna redogöra för trädalgoritmer, komprimering av data (exempelvis Huffmankodning för de som läser ML), veta skillnaden mellan olika traverseringsordningar (inklusive pre-, post och inorder) samt geografiska informationssystem och många fler. veta hur träd kan implementeras på olika sätt. Lars Larsson Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning 2 Träd 3 Lars Larsson Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Grundläggande termer Gränsyta för träd Trädtyper och ordning Träd 4 Grundläggande termer Gränsyta för träd Trädtyper och ordning Elementen i ett träd kallas noder och har en position och en etikett. Förbindelserna mellan noderna kallas för grenar. Träd är en familj av datastrukturer som alla bygger på att ett ändligt antal element är hierarkiskt ordnade genom en förfaderrelation. Det finns ett element som är (mer eller mindre avlägset) förfader till alla andra i strukturen. Datatypen är homogen, i betydelsen att vi endast sparar en typ av värden i den. En nod p som ligger under en annan nod q kallas för dess barn. q är förälder till p. Noder på samma nivå kallas för syskon. En föräldralös nod kallas för rot (finns bara en i varje träd) och barnlösa noder kallas för löv. En nod p och dess avkomma heter delträd. p är då rot i delträdet. Lars Larsson Träd 5 Lars Larsson Träd 6 Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Grundläggande termer Gränsyta för träd Trädtyper och ordning Kursboken har lite ovanliga definitioner gällande höjd och djup av träd. På kursen (och i verkligheten) använder vi istället dessa: Maximal höjd innebär att vi inte kan öka höjden genom omflyttning av element. Hur ser sådana träd alltid ut? Höjden h(x) för en nod x är antalet bågar på den längsta grenen i det (del-)träd där x är rot. Minimal höjd innebär att man inte kan flytta om noder och få en lägre höjd. Djupet d(x) för en nod x är antalet bågar från x upp till roten. Lars Larsson Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Träd Grundläggande termer Gränsyta för träd Trädtyper och ordning 7 Lars Larsson Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Grundläggande termer Gränsyta för träd Trädtyper och ordning Träd 8 Grundläggande termer Gränsyta för träd Trädtyper och ordning Gränsytan finns i boken – vi tar inte upp den här! Navigeringsorienterad specifikation: trädet betraktas som en struktur av noder som är relaterade till varandra på det sätt vi beskrivit hittills. Ordnat träd – syskonen är linjärt ordnade. Oordnat träd – syskonen har ingen inbördes ordning. Urträd – generell träddatatyp som inte specificerar någon relation mellan syskon alls, utan låter en annan datatyp hantera detta. Ordnat träd och oordnat träd kan ses som specialfall av urträd med bestämda datatyper som hanterar syskonordningen. Delträdsorienterad specifikation: trädet ses som sammansättningar av delträd, alltså en rekursiv datatyp. Uppsättningen operationer i gränsytan speglar detta (exempelvis finns join och split). Vilken specifikation är bäst? Varning: ordnad betyder inte sorterad! Trädet förändras nodvis: navigeringsorienterad. Trädet delas upp och slås samman med andra träd: delträdsorienterad. Lars Larsson Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Träd 9 Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Grundläggande termer Gränsyta för träd Trädtyper och ordning Sorterad – elementens värden avgör hur elementen skall ordnas i datatypen. Träd Träd 10 Grundläggande termer Gränsyta för träd Trädtyper och ordning Riktade träd – man kan bara gå i en riktning (nedåtriktade träd saknar operationen Parent och uppåtriktade saknar operationen Children). Jämför med riktad lista! Ordnad – elementen i datatypen har någon inbördes relation som avspeglas i datatypens struktur. Lars Larsson Lars Larsson Binära träd – varje nod kan ha maximalt två barn, och barnen benämns ”höger” respektive ”vänster”. Dessa träd är så viktiga att vi skall ge dem lite mer utrymme. 11 Lars Larsson Träd 12 Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Strukturen hos binära träd är mycket viktig, och följande binära träd är alltså inte strukturellt lika: För ett binärt träd med n antal noder och höjden h gäller: h ≤ n − 1 (maximala höjden) h ≥ log2 (n + 1) − 1 ty Antalet noder på djupet i är 2i , alltså 1, 2, 4, . . . Antalet noder totalt i trädet är n ≤ 2(h+1) − 1 Ett träd har minimal höjd om n > 2h − 1 vilket ger log2 (n + 1) − 1 ≤ h < log2 (n + 1) Alltså är h av O(log2 (n))! Lars Larsson Träd 13 Lars Larsson Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Traversering Traversering Traversering Traversering Traversering Traversering Slå ihop Dela upp Traversera Beräkna (innehåller en hel del traversering) 15 – – – – – bredden först djupet först djupet först, preorder djupet först, inorder djupet först, postorder Höjd Binära träd där varje nod antingen är ett löv eller har två barn kallas för fullt binära träd. Dessa tillåter dålig balans (exempelvis är det OK att alla högerbarn är löv, men att vänsterbarnen har två barn). Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning – – – – – Djup Binära träd kallas kompletta om de fylls på från vänster till höger, en nivå i taget. De har rätt bra balans. Träd Traversering Traversering Traversering Traversering Traversering Traversering 14 Våra mest basala algoritmer för träd är: Om vänster och höger delträd är ungefär lika stora har vi balans och vägen till en godtycklig nod är O(log2 (n)). Lars Larsson Träd Lars Larsson Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning bredden först djupet först djupet först, preorder djupet först, inorder djupet först, postorder Träd Traversering Traversering Traversering Traversering Traversering Traversering 16 – – – – – bredden först djupet först djupet först, preorder djupet först, inorder djupet först, postorder Rita av det här trädet, vi kommer att behöva det fyra gånger: Många tillämpningar bygger på att vi går igenom trädet systematiskt (traverserar) och exempelvis: Söker efter ett element. Transformerar strukturen, alltså exempelvis balanserar trädet eller sorterar dess element. Filtrerar ut element med en viss egenskap. Lars Larsson Träd 17 Lars Larsson Träd 18 Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Traversering Traversering Traversering Traversering Traversering Traversering – – – – – Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning bredden först djupet först djupet först, preorder djupet först, inorder djupet först, postorder Varje nod besöks bara en gång, alltså (förutsatt operationer på konstant tid) O(n). Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Traversering Traversering Traversering Traversering Traversering Traversering 19 – – – – – Traversering Traversering Traversering Traversering Traversering Traversering – – – – – bredden först djupet först djupet först, preorder djupet först, inorder djupet först, postorder Inorder – först besöks det första delträdet inorder, sedan föräldern, följt av de övriga delträden (inorder). I stort sett bara intressant för binära träd. Postorder – barnen besöks (i postorder) före föräldern. Vi använder lämpligen en stack och eftersom vi bara besöker varje nod exakt en gång, så är algoritmen O(n). 21 – – – – – Traversering Traversering Traversering Traversering Traversering Traversering 20 Preorder – föräldern besöks innan dess barn (i preorder) Ordningen i det uppritade trädet blir: a, b, c, d, e, f, g, h, i, j. Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Träd Djupet först går ut på att varje gren följs från roten till löven, i någon ordning: q := EmptyQueue q.enqueue(T.getRoot()) while(q is not empty) do node := q.dequeue() q.enqueueMany(node.getAllChildren()) compute(node) done Träd Lars Larsson Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning bredden först djupet först djupet först, preorder djupet först, inorder djupet först, postorder Algorithm bfOrder(Tree T): input: a tree T to be traversed Lars Larsson bredden först djupet först djupet först, preorder djupet först, inorder djupet först, postorder for each level L of T do for each node in L do compute(node) // gör något med noden done done I stort sett hela implementationen döljs av den här algoritmen! Hur skulle ni implementera bredden-först-traversering? Använder lämpligen en kö. Träd – – – – – Algorithm bfOrder(Tree T): input: a tree T to be traversed Vi kan undersöka trädet nivåvis. Först roten, sedan dess barn, sedan rotens barnbarn, och så vidare. Lars Larsson Traversering Traversering Traversering Traversering Traversering Traversering Lars Larsson Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning bredden först djupet först djupet först, preorder djupet först, inorder djupet först, postorder Träd Traversering Traversering Traversering Traversering Traversering Traversering 22 – – – – – bredden först djupet först djupet först, preorder djupet först, inorder djupet först, postorder Algorithm preOrder(Tree T): input: a tree T to be traversed Algorithm preOrderBinary(BinTree T): input: a binary tree T to be traversed compute(T.getRoot()) for each child w of root T do preOrder(w) done compute(T.getRoot()) preOrderBinary(T.getLeftChild()) preOrderBinary(T.getRightChild()) Ordningen i det uppritade trädet blir: a, b, c, d, f, g, e, h, i, j. Lars Larsson Träd 23 Lars Larsson Träd 24 Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Traversering Traversering Traversering Traversering Traversering Traversering – – – – – Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning bredden först djupet först djupet först, preorder djupet först, inorder djupet först, postorder Traversering Traversering Traversering Traversering Traversering Traversering – – – – – bredden först djupet först djupet först, preorder djupet först, inorder djupet först, postorder Algorithm inOrder(Tree T): input: a tree T to be traversed Algorithm inOrderBinary(BinTree T): input: a binary tree T to be traversed node := T.getRoot() inOrder(T.getFirstChild()) compute(node) for each child w of node (except first) do inOrder(w) done inOrderBinary(T.getLeftChild()) compute(T.getRoot()) inOrderBinary(T.getRightChild()) Ordningen i det uppritade trädet blir: b, a, c, f, d, g, h, e, i, j. Lars Larsson Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Träd Traversering Traversering Traversering Traversering Traversering Traversering 25 – – – – – Lars Larsson Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning bredden först djupet först djupet först, preorder djupet först, inorder djupet först, postorder Träd Traversering Traversering Traversering Traversering Traversering Traversering 26 – – – – – bredden först djupet först djupet först, preorder djupet först, inorder djupet först, postorder Algorithm postOrder(Tree T): input: a tree T to be traversed Algorithm postOrderBinary(BinTree T): input: a binary tree T to be traversed for each child w of T.getRoot() do postOrder(w) done compute(node) postOrderBinary(T.getLeftChild()) postOrderBinary(T.getRightChild()) compute(T.getRoot()) Ordningen i det uppritade trädet blir: b, c, f, g, d, h, i, j, e, a. Lars Larsson Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Träd 27 Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Fält n-länkad struktur Barnen som lista Trädda binära träd + Mycket sparsamt med minnet. 28 Fält n-länkad struktur Barnen som lista Trädda binära träd Problem: hur ser fältet ut om vi har extremt dålig balans, och bara har högerbarn? – Fält är statiska – vi har bestämt maximalt antal noder. Träd Träd Binära träd har en egenskap som kan utnyttjas då de implementeras med fält. Om vi indexerar fältet från 0 och upp, så har noden med index k noderna med index 2 × k + 1 och 2 × k + 2 som barn. Exempelvis: roten (index 0) har som barn noderna med index 1 och 2. Vi kan spara information om en nods förälder i ett fält, tillsammans med dess värde. Traversering blir dock mycket svår – vi måste gå igenom hela fältet för att hitta vilka noder som är barn till en viss nod, vilket är O(n), alltså dyrt. Lars Larsson Lars Larsson 29 Lars Larsson Träd 30 Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Fält n-länkad struktur Barnen som lista Trädda binära träd Vi kan låta varje nod vara en n-länkad struktur, alltså att varje nod innehåller referenser till sina barn (och eventuellt sin förälder). Antalet barn är begränsat till att vara maximalt lika med n. Fält n-länkad struktur Barnen som lista Trädda binära träd Definitionen av binära träd säger att vi maximalt kan ha 2 barn, så en konstruktion med två länkar för barnen och en för föräldern är mycket vanlig och den allra vettigaste. + Antalet noder är inte begränsat. – Begränsar antalet barn per nod. – Eventuellt dåligt utnyttjande av minnet – alla noder kanske inte har n barn? Lars Larsson Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Träd 31 Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Fält n-länkad struktur Barnen som lista Trädda binära träd Vad händer om vi låter barnaskaran vara representerade av en lista (eller en mängd om vi har oordnade träd)? Träd 33 Vi har introducerat den terminologi som används gällande träd, sett exempel på hur man kan traversera träd och slutligen hur de kan implementeras. Binära träd har getts speciellt utrymme, eftersom de är mycket vanliga och kan vara lättare att resonera kring i samband med traverseringsordningar. Träd 32 Fält n-länkad struktur Barnen som lista Trädda binära träd Ett sätt att snabba upp är att låta lövens outnyttjade barnlänkar peka på den nod som ligger som nästa i ordningen, typiskt inorder. Dagens föreläsning Bakgrund och motivation Mål Terminologi och definitioner Binära träd Trädalgoritmer Implementation Sammanfattning Lars Larsson Träd Inorder-traversering är mycket vanlig för binära träd, och vi vill helst inte använda den rekursiva algoritmen vi presenterade tidigare (rekursion är generellt dyrt). Vi slipper problem med dåligt minnesutnyttjande, vi begränsas inte till ett visst antal av varken barn eller noder och allt är frid och fröjd! Lars Larsson Lars Larsson 35 Lars Larsson Träd 34