Översikt Trädstrukturer och grafer Trädstrukturer Grundbegrepp Binära träd Sökning i träd Grafer Sökning i grafer Programmering tillämpningar och datastrukturer Varför olika datastrukturer? Olika datastrukturer är bra på olika saker Olika prestanda för inläggning, sökning, sortering, etc. Ex. snabbt att lägga in nytt element i sorterat träd Heaps (behöver inte jämföra alla element som är mindre) Hierarkisk struktur Träd Används för att representera Grafiska strukturer Fönster, panel i fönster, etiketter i panel, Filstruktur Virtuella världar Stad, hus, tak, väggar, rum, möbler Programmering tillämpningar och datastrukturer Programmering tillämpningar och datastrukturer Grundbegrepp Grundbegrepp nod gren rot löv Programmering tillämpningar och datastrukturer Programmering tillämpningar och datastrukturer 6
Grundbegrepp Grundbegrepp förälder vänster delträd höger delträd syskon barn Programmering tillämpningar och datastrukturer 7 Programmering tillämpningar och datastrukturer 8 Grundbegrepp Egenskaper hos träd nodens nivå = trädets höjd = Binära, trinära Max två, tre delträd Balanserat Ungefär samma djup (maxnivå) överallt Fullt (full) Inga ofyllda delträd Fullständigt (complete) Ofyllda delträd ligger längst ner till höger Programmering tillämpningar och datastrukturer 9 Programmering tillämpningar och datastrukturer 0 Binära träd Binärt sökträd Max två delträd För alla delträd T måste ett av följande gälla: T är tom / log ^ + T har max två delträd, T v och T h, sådan att alla element i T v är mindre än roten, och alla element i T h är större än roten 8 Programmering tillämpningar och datastrukturer Programmering tillämpningar och datastrukturer
Binärt sökträd Balanserat träd 6 8 Vill ha så lika nivåer i trädet som möjligt Minimerar antal noder man behöver gå igenom för att nå löven För balanserat binärt träd i snitt log n I sorterade balanserade träd får man alltså optimal söktid (= trädets höjd) 7 9 Programmering tillämpningar och datastrukturer Programmering tillämpningar och datastrukturer Obalanserat träd Balanserat träd Ger dåliga prestanda på sökalgoritmer Programmering tillämpningar och datastrukturer Programmering tillämpningar och datastrukturer 6 Alla noder har två barn Fullt träd Komplett träd Båda delträden lika djupa på alla nivåer (alla löv ligger på samma nivå) 6 7 Programmering tillämpningar och datastrukturer 7 Programmering tillämpningar och datastrukturer 8
Komplett träd Komplett träd Komplett träd med höjd h, om alla löv ligger på djup h eller h- De löv som ligger på djup h- måste vara på vänster sida av trädet Dvs. löven fylls på från vänster på nedersta raden Programmering tillämpningar och datastrukturer 9 Programmering tillämpningar och datastrukturer 0 Skog Bredden först / + Bredden först: Undersök roten först Rotens delträd bildar en skog Undersök varje träd i skogen rekursivt 6 log ^ 7 8 9 8 Programmering tillämpningar och datastrukturer Programmering tillämpningar och datastrukturer Bredden först: Betar av rötterna, en nivå i taget Djupet först: Undersöker första delträd helt och hållet innan man går över till nästa delträd Roten kan antingen undersökas först eller mellan två delträd eller efter alla delträd Djupet först, roten först (preorder, Euler tour): Undersök först roten Undersök sedan vänster delträd (helt och hållet) Till sist höger delträd Programmering tillämpningar och datastrukturer Programmering tillämpningar och datastrukturer
Djupet först, roten först (preorder, Euler tour): 6 Djupet först, roten i mitten (inorder): Undersök först vänster delträd Undersök sedan roten Till sist höger delträd 7 8 9 0 (/ (log 8) ) (+ (^ )) Programmering tillämpningar och datastrukturer 6 Programmering tillämpningar och datastrukturer Djupet först, roten i mitten (inorder): 7 Djupet först, roten sist (postorder): Undersök först vänster delträd Undersök sedan höger delträd Till sist roten 6 9 8 0 ((log 8) / ) ( + ( ^ )) Programmering tillämpningar och datastrukturer 7 Programmering tillämpningar och datastrukturer 8 Djupet först, roten sist (postorder): 0 9 8 6 7 ((8 log) /) ( ( ^ ) +) Programmering tillämpningar och datastrukturer 9 public class BinaryTree { protected Node root; public BinaryTree() { Implementation av träd protected class Node { protected BinaryTree left; protected BinaryTree right; protected Object Contents; Programmering tillämpningar och datastrukturer 0
Kallas för grafer Cykliska strukturer Uppstår när finns väg horisontellt till syskon eller syskonbarn Ex. vägar som återför en till ställen man redan varit på, trots att man hela tiden går framåt (labb ) Kan ge upphov till oändliga loopar Grafer Noder sammankopplade med bågar i ett nätverk nod båge Riktad graf (dvs. riktade bågar) Programmering tillämpningar och datastrukturer Programmering tillämpningar och datastrukturer Representation av grafer Mängdteoretisk Par av noder som sammanbinds av båge { <nod, nod >, <nod n, nod k > Inriktad på Slå samman grafer (union) Skära ut delgrafer (delmängd) Programmering tillämpningar och datastrukturer Representation av grafer Navigeringsorienterad Specifikation av de noder man kan gå till i ett steg från varje enskild nod Inriktad på att kunna gå i grafen Två sätt Lista av grannar Array där element <n n > representerar en båge från nod n till nod n Programmering tillämpningar och datastrukturer Lista av grannar (adjacency list) Array av bågar (adjacency matrix) till från Programmering tillämpningar och datastrukturer Programmering tillämpningar och datastrukturer 6 6
Interface till grafer Implementation av grafer Teoretiskt: boolean isempty() boolean hasnoedges() I java: boolean isempty() <<interface>> EdgeIterator <<interface>> Graph neighbours(node) choosenode() addnode(node), deletenode(node) addedge(edge), deleteedge(edge) clear() Set getroots() // returnerar mängd av grannoder Iterator<E> iterator() NodeData getnodedata(node) int size() boolean contains(object o) void clear() MatrixGraph Iter AbstractGraph ListGraph Iter Edge Programmering tillämpningar och datastrukturer 7 Programmering tillämpningar och datastrukturer 8 AbstractGraph // konstruktor AbstractGraph(int numv, boolean directed) getnumv() // get number of vertices boolean directed() ListGraph // konstruktor ListGraph(int numv, boolean directed) insert(edge e) boolean isedge() // sätt att komma åt grannar till en nod EdgeIterator edgeiterator(int source, int dest) Programmering tillämpningar och datastrukturer 9 Programmering tillämpningar och datastrukturer 0 // konstruktor Iterator(int source) boolean hasnext() Edge next() ListGraph.Iter Gå igenom en graf Kan gå bredden först eller djupet först (precis som för träd) Bredden först hoppar mellan delgrafer (delträd) och kan i vissa sammanhang verka onaturlig Anropar i sin tur metoder i klassen LinkedList.Iterator Programmering tillämpningar och datastrukturer Programmering tillämpningar och datastrukturer 7
Gå igenom en graf Gå igenom en graf Viktigt att hålla reda på redan besökta noder Plus kanske i vilken ordning noderna besöktes Använd lista eller kö för att representera besökta noder Programmering tillämpningar och datastrukturer Programmering tillämpningar och datastrukturer Djupet först genomsökning Lista av grannar (adjacency list). Markera nuvarande nod n som besökt och lägg in bland öppnanoder (visited). För varje nod g som ligger ett steg från nuvarande nod: Om g inte har blivit besökt tidigare Sök rekursivt med n som nuvarande nod. Markera m som avslutad (uttömmade genomsökt) och lägg m i stängdanoder (finished) Programmering tillämpningar och datastrukturer Programmering tillämpningar och datastrukturer 6 Lista av grannar (adjacency list) Algoritm för djupet först boolean[] true visited (open) boolean[] finished (closed). Markera nuvarande nod n som visited. För varje grannod g till nod n Om g inte har blivit visited Sök rekursivt med g som nuvarande nod // Notera att backtracking sköts automatiskt eftersom rekursivt implementerat. Markera n som finished Programmering tillämpningar och datastrukturer 7 Programmering tillämpningar och datastrukturer 8 8
Pseudo-kod för djupet först Pseudo-kod för djupet först public DepthFirstSearch(Graph graph) { int i; // konstruktor public void depthfirstsearch(intcurrent) { int neighbor; this.graph = graph; int n = graph.getnumv(); visited = new boolean[n]; // initieras automatiskt till finished = new boolean[n]; // initieras automatiskt till for (i = 0; i < n; i++) { // visit all nodes, even if isolated from rest of graph if (!visited[i]) { depthfirstsearch(i); visited[current] = true; Graph.EdgeIterator itr = graph.edgeiterator(current); while (itr.hasnext()) { neighbor = itr.next().getdest(); if (!visited[neighbor]) { depthfirstsearch(neighbor); finished[current] = true; Programmering tillämpningar och datastrukturer 9 Programmering tillämpningar och datastrukturer 0 Exempel djupet först Utskrift från djupet först oriktad graf 0 markera som visited 6 Visiting node 0 Visiting node Visiting node Visiting node Finished node Finished node Finished node Visiting node Visiting node Visiting node 6 Finished node 6 Finished node Finished node Finished node 0 Programmering tillämpningar och datastrukturer Programmering tillämpningar och datastrukturer 9