lgoritmer och datastrukturer, föreläsning 11 enna föreläsning behandlar grafer. En graf har en mängd noder (vertex) och en mängd bågar (edge). Ett exempel är: E F G H Z enna graf har följande mängd av noder: {,,,, E, F, G, H, Z en har följande mängd bågar: {<, >, <, >, <, >, <, >, <, E>, <E, F>, <G, H>, <H, Z> Observera att bågarna är riktade! Vi definierar en nods utgrad som antal bågar som går ut från noden. En nods ingrad är antalet bågar in till noden. En väg från nod till nod är en mängd noder via vilka man kan gå från till via bågar. Observera att man får bara gå i pilens riktning på en båge. En cykel är en väg där första och sista noden är samma. En enkel cykel är en cykel där alla noder utom den sista och den första är olika. I en oriktad graf finns det ingen riktning på bågarna, man får gå åt båda hållen. Man kan se en oriktad graf som en riktad graf där det alltid finns en båge från till om det också finns en från till. En graf kallas sammanhängande om det finns en väg mellan alla noder. Grafen i figuren ovan är alltså inte sammanhängande. en har två komponenter. Ofta finns det något värde på bågarna i en graf. et kan till exempel representera längden av vägen mellan två noder eller kostnaden för att gå mellan två noder.
Representation av grafer en enklaste representationen är att använda en matris. ntag till exempel att vi har följande graf: 5 2 7 3 en kan representeras av följande matris eller tabell: null null null 5 null 2 3 null null null 7 null null null En nackdel är att om grafen är stor så blir matrisen mycket stor. Ofta så finns det bara bågar mellan noder som ligger nära varandra och då kommer det oftast att stå null i tabellen. En annan representation är närhetslistan. en ser ut så här för grafen ovan: 5 2 3 7 Fyrkanterna längst till vänster representerar noderna. I fyrkanterna finns data som hör hop med noden. e mer avlånga fyrkanterna representerar bågarna, här finns också data som hör ihop med bågen. e bågar som radas upp till vänster om en nod är de bågar som utgår från noden. Pilen som går från varje båge till en nod visar till vilken nod som bågen går. Representation i Java I Java använder man vanligtvis tre olika klasser för att representera grafer. Iden är samma som för träd och länkade listor, att man har en klass för trädet eller listan och en för noderna som i sin tur kan innehåller data. Vi använder en nodklass, en bågklass och en grafklass. En skiss av dem följer nedan.
Vi börjar med nodklassen. en kan se ut så här: public class Vertex{ //Nodklassen public Vertex nextvertex(){ public Edge firstedge(){ Om till exempel nod i grafen ovan anropar nextvertex så får man etc. Om anropar nextvertex() så blir resultatet null eftersom det inte finns någon nästa nod. Om nod anropar firstedge() så får man bågen som är strax till vänster om den. ågklassen kan ha föjande principiella utseende: public class Edge{ public Edge nextedge(){ public Vertex endpoint(){ Om man anropar nextedge() så får man den båge som finns till höger i närhetslistan. Om det inte finns någon så får man null. Om man anropar endpoint() så får man reda på vilken nod som bågen pekar på. Själva grafklassen kan se ut så här: public class igraph{ public Vertex firstvertex(){ public void insertvertex(vertex v){ public void insertedge(vertex v, Vertex w, Edge e){ Om man anropar firstvertex() så får man den första noden i grafen, i närhetsgrafen ovan är det nod. Exempel ntag att vi vill gå igenom alla noder i en graf g oberoende av bågar. å kan man göra så här: Vertex v = g.firstvertex(); while (g!= null){ //Gör något med noden här v = v.nextedge(); Observera att man inte alls följer bågarna i grafen när man gör så här. Exempel ntag att vi vill besöka alla grannarna till noden v. Så här kan man göra då: Edge e = v.firstedge(); Vertex w = e.endpoint(); //ehandla noden
tt gå igenom grafer Vi ska titta på två sätt att gå igenom (traversera) grafer genom att följa bågarna. I bägge fallen behövs det en startnod. en kan metoden firstvertex() i grafklassen förse oss med. en ena metoden kallas djupet först och den andra bredden först. jupet först Man använder rekursion för att gå igenom noderna. Man makerar noder som besökta när man har besökt dem, varje nod har ett booleskt attribut visited som används för detta. Man kan endast komma till noder som kan nås från startnoden. et betyder att om grafen har flera komponenter så kommer man bara att besöka alla noder i startnodens komponent. Metoden för detta placeras lämpligen i grafklassen. Koden kan se ut så här: public void depthfirst(vertex v){ v.visited = true; // Gör något med noden Edge e = v.firstedge(); Vertex w = e.endpoint(); if (!w.visited) depthfirst(w); redden först Här besöker man först alla startnodens grannar, sedan grannarnas grannar etc. Också här används ett boolskt attribut för att markera att en nod är besökt. Koden kan se ut så här: public void breadthfirst(vertex v){ v.visited = true; //Gör något med noden q.add(v); while (!q.isempty()){ Vertex x = q.remove; Edge e = x.firstedge(); Vertex w = endpoint(); if (!w.visited){ w.visited = true; //Gör något med noden; q.add(w); q kan vara t ex en lista i vilken man lagrar noder vars grannar man ska besöka. Man besöker bara de noder som kan nås från startnoden.
Läsavisningar i gamla boken vsnitt 1.1