Datastrukturer och algoritmer Föreläsning 11 Datastrukturer och algoritmer Innehåll Mängd Lexikon Heap VT08 Kapitel 13.1-13.2, 13.4-13.6, 14.4 och 14.7 i kursboken Datastrukturer och algoritmer Mängd – modell VT08 En påse, dock inte riktigt bra eftersom man kan ha mängder med gemensamma element o går inte ha saker i flera påsar samtidigt inte vill att en mängd ska kunna innehålla andra mängder o skillnad jämfört med matematiken! o inga problem att lagra påsar i påsen Datastrukturer och algoritmer Mängd – organisation VT08 En oordnad samling av element som är av samma typ. Grundmängden behöver inte vara ändlig (heltal) men dataobjekten är ändliga. Kan inte innehålla två likadana värden. En mängd kan inte innehålla mängder. Datastrukturer och algoritmer Mängd – specifikation VT08 abstract datatype Set(val) Empty()->Set(val) Single(v:val)->Set(val) Insert(v:val,s:Set(val))->Set(val) Union(s:Set(val),t:Set(val))->Set(val) Intersection(s:Set(val),t:Set(val))->Set(val) Difference(s:Set(val),t:Set(val))->Set(val) Isempty(s:Set(val))->Bool Member-of(v:val,s:Set(val))->Bool Choose(s:Set(val))->val Remove(v:val,s:Set(val))->Set(val) Equal(s:Set(val),t:Set(val))->Bool Subset(s:Set(val),t:Set(val))->Bool Datastrukturer och algoritmer Mängd – specifikation VT08 Alla metoder som finns i boken behövs inte. Empty, IsEmpty, Insert, Choose och Remove skulle räcka. Man har tagit med de vanliga matematiska mängdoperationerna. Datastrukturer och algoritmer Konstruktion av mängd VT08 Går i princip att konstrueras i vilken dynamisk datatyp som helst. Men inte säkert att det blir effektivt... Man måste hantera dubbletter. Mängd som lista har två alternativ: Se till att listan inte har dubbletter (krav på SetInsert och Union) Låt listan ha dubbletter (krav på Equal, Remove, Intersection, Difference) Datastrukturer och algoritmer Konstruktion av mängd som lista VT08 Komplexitet: Metoder som kräver sökningar i listan O(n) Binära mängdoperationerna kräver (pga nästlad iteration) O(m*n) Listan kan konstrueras på olika sätt. Sorterad lista tex är effektivare för de binära mängdoperationerna. + Grundmängden kan vara mycket stor + Delmängderna kan både vara mycket små och mycket stora utan utrymmesförluster (om man implementerar listan på rätt sätt) - Flera operationer blir slöa jämfört med andra val. Datastrukturer och algoritmer VT08 Konstruktion av mängd som bitvektor En bitvektor är en vektor med elementvärden av typen Bit = {0,1} Ibland tolkas 0 och 1 som falskt resp. sant, dvs Bit identifieras som datatypen Boolean Grundmängden måste ha en diskret linjär ordning av elementen. Dvs, man kan numrera dem. Bit k i bitvektorn motsvarar det k:te elementet i grundmängden. Biten är 1 om elementet ingår i mängden. Datastrukturer och algoritmer Konstruktion av mängd som bitvektor Dvs man gör operationen samtidigt på alla element i vektorn. Detta gör många metoder effektiva. + - VT08 Om bitvektorn finns implementerad som ett eller flera ord i datorns primärminne kan man utnyttja maskinoperationer. Relativt effektiv i allmänhet, mycket effektiv som ovan. Grundmängden måste vara ändlig och i praktiken rätt så liten. Reserverar minne proportionellt mot grundmängdens storlek. Om man har många små mängder i en tillämpning blir det dålig effektivitet i minnesutnyttjandet. Datastrukturer och algoritmer VT08 public class IntSet { private boolean[] set; private final int MAXLEN=100; public IntSet(){ set = new boolean[MAXLEN]; } public void single(int num){ set = new boolean[MAXLEN]; set[num] = true; } public void insert(int num){ set[num] = true; } Mängd av heltal som boolsk vektor Datastrukturer och algoritmer VT08 public IntSet union(IntSet t){ IntSet newSet = new IntSet(); for(int i=0;i<MAXLEN;i++){ if (set[i] || t.memberOf(i)) newSet.insert(i); } return newSet; } public IntSet intersection(IntSet t){ IntSet newSet = new IntSet(); for(int i=0;i<MAXLEN;i++){ if (set[i] && t.memberOf(i)) newSet.insert(i); } return newSet; } Datastrukturer och algoritmer VT08 public IntSet difference(IntSet t){ IntSet newSet = new IntSet(); for(int i=0;i<MAXLEN;i++){ if (set[i] && !t.memberOf(i)) newSet.insert(i); } return newSet; } public boolean isEmpty(){ for(int i=0;i<MAXLEN;i++){ if (set[i]) return false; } return true; } public boolean memberOf(int num){ return set[num]; } Datastrukturer och algoritmer VT08 public int choose(){ for(int i=0;i<MAXLEN;i++){ if (set[i]) return i; } // Här borde vi skapa ett undantag! return -1; } public void remove(int num){ set[num] = false; } public boolean equal(IntSet t){ for(int i=0;i<MAXLEN;i++){ if (set[i] != t.memberOf(i)) return false; } return true; } Datastrukturer och algoritmer VT08 public boolean subSet(IntSet t){ for(int i=0;i<MAXLEN;i++){ if (t.memberOf(i) && !set[i]) return false; } return true; } public void printOut(){ System.out.print("{"); for (int i=0; i<MAXLEN; i++){ if(set[i]) System.out.print(i+ ", "); } System.out.println("}"); } } Datastrukturer och algoritmer Lexikon VT08 En förenklad mängd där man tagit bort union, intersection, difference, subset och equal. Kvar är det man behöver för att kunna hålla ordning på en samling objekt: empty isempty(s) insert(v, s) remove(v, s) memberOf(v, s) Datastrukturer och algoritmer Lexikon VT08 Ett lexikon är som en tabell utan tabellvärden. Alltså fungerar datatypen lexikon inte som en uppslagsbok (lexikon). Saknar metoder för att kombinera lexikon till nya lexikon. Oftast behöver man bara skapa ett lexikon en enda gång. Lexikon är en solitär datatyp. Man kan bara göra modifieringar av isolerade dataobjekt. En icke-solitär datatyp har stöd för att kombinera/bearbeta två eller flera dataobjekt. Datastrukturer och algoritmer Konstruktion av lexikon VT08 Kan få betydligt effektivare konstruktioner när antalet och typen av metoder är begränsade. Två konstruktioner av lexikon: Lexikon som Hashtabell (redan gjort, förel. 4) Lexikon som Binärt sökträd Lexikon som Trie (nästa föreläsning) Eftersom Lexikon är så likt Tabell kan dessa konstruktioner med små ändringar bli effektiva konstruktioner av en tabell. Datastrukturer och algoritmer Binärt sökträd VT08 Används för sökning i linjära samlingar av dataobjekt, specifikt för att konstruera tabeller och lexikon. I ett vanligt binärt träd kan man i värsta fall måsta besöka alla noder för att hitta ett element. Datastrukturer och algoritmer Binärt sökträd – Organisation VT08 Ett binärt träd som är sorterat med avseende på en sorteringsordning R av etikettypen så att I varje nod N gäller att alla etiketter i vänster delträd går före N som i sin tur går före alla etiketter i höger delträd. Alla noder är definierade. Datastrukturer och algoritmer Informell specifikation Skiljer sig från ett vanligt binärt träd: Alla noder måste ha etiketter. o Ta bort Create, Has-Label och Set-Label och inför Make som skapar rotnod med värde. o Insert-operationerna utökas med ett etikettvärde. Man ska kunna ta bort inre noder också, inte bara löv. o Positionsparametern i Delete-node behöver inte peka på ett löv. o När man rycker bort en inre nod slits trädet sönder. Hur lagar man det? Är nedåtriktat o Parent kan utelämnas. Eftersom trädet är sorterat kan man inte få stoppa in ett nytt element vart som helst. o Måste uppfylla sorteringsordningen. VT08 Datastrukturer och algoritmer Varför sorterat träd? Det går snabbare att söka i strukturen… För binärt sökträd: Kolla om det sökta värdet finns i den aktuella noden. Om inte sök rekursivt nedåt i vänster eller höger delträd beroende på om det sökta elementet kommer före eller efter nodens värde i sorteringsordningen. Om det binära trädet är komplett: Värstafallskomplexitet för sökning O(log n) för ett träd med n noder. Hur ser man till att trädet blir komplett vid insättning? o Kommer lite senare när vi pratar om en Heap VT08 Datastrukturer och algoritmer Insättning i binärt sökträd Bild från sidan 289 i Janlert L-E., Wiberg T., Datatyper och algoritmer, Studentlitteratur, 2000 Se också animeringen på sidan http://people.ksp.sk/~kuko/bak/big (välj BST) VT08 Datastrukturer och algoritmer Borttagning av nod i binärt sökträd VT08 Hur tar bort en nod mitt i ett träd? Om den borttagna noden bara hade ett delträd: o Lyft upp det ett snäpp Om den borttagna noden hade två delträd: o Välj noden med det minsta värdet i höger delträd som ersättning (alternativt noden med största värdet i vänster delträd). Detta är standardkonstruktionen, är upp till den som implementerar trädet. De vanligaste tillämpningarna är inte beroende av denna detalj. Viktigt att visar sitt beslut i specifikation och dokumentation. Datastrukturer och algoritmer VT08 → → Bild från sidan 289-290 i Janlert L-E., Wiberg T., Datatyper och algoritmer, Studentlitteratur, 2000 Datastrukturer och algoritmer Varför inte ändra gränsytan? VT08 Eftersom man inte får sätta in ett nytt element vart som helst så kanske man lika gärna kan ersätta insert-left och insert-right med en metod place som automatiskt placerar det rätt? På samma sätt ersätta delete-node(pos, bt) med remove(val, bt)? Bägge dessa metoder ligger på en högre abstraktionsnivå än övriga metoder i gränsytan. Place implementerar man i huvudsak med hjälp av andra metoder i gränsytan vilket är lite märkligt. Strukturen döljs (för oss) och blir mer lik en mängd. Datastrukturer och algoritmer Tillämpningar av Binärt sökträd VT08 Framför allt till konstruktioner av Lexikon och Tabell. Notera att inorder-traversering av binärt sökträd ger en sorterad sekvens av de ingående elementen. Kan alltså sortera element genom att stoppa in dem ett och ett i ett tomt Binärt sökträd och sedan traversera det. Datastrukturer och algoritmer Generaliseringar VT08 Ett binärt sökträd underlättar sökning i en endimensionell datamängd. Lätt att generalisera detta till sökning i en 4dimensionell datamängd (quadtree) eller så hög dimension man önskar (tex octtree). Datastrukturer och algoritmer Quadtree (Fyrträd) VT08 Organiserat som ett binärt träd med förgreningsfaktor 4 istället för 2. Tolkning (vanligast): Rotnoden delar in den givna ytan (oftast kvadrat) i fyra lika stora kvadrater. Vart och ett av de fyra barnen delar i sin tur sin kvadrat i fyra osv. Inga koordinater behöver lagras i inre noder. Kan användas för att lagra lägesinformation för punktformiga grafiska objekt. Datastrukturer och algoritmer Quadtree – forts. VT08 Man kan också använda det för att representera kurvor och ytor. Svarta kvadranter – fylls helt av objektet Grå kvadranter – fylls delvis av objektet Vita kvadranter – innehåller inte objektet Exempel på tillämpning GIS qtdemo i Matlab på peppar Datastrukturer och algoritmer På Matlabs hemsida om Image processing toolbox VT08 Image and a Representation of Its Quadtree Decomposition Datastrukturer och algoritmer Heap/Hög VT08 Ett partiellt sorterat binärt träd Etiketterna är sorterade efter en relation R så att a är förälder till b endast om a är före b i ordningen som ges av R. Insättningar och borttagningar görs så att trädet hålls komplett. Insert O(log n), Delete-first O(log n) Kan användas tex för att konstruera en prioritetskö. Datastrukturer och algoritmer Insättning i en Heap VT08 Placera den nya noden på första lediga plats. Låt sedan noden vandra uppåt i heapen tills det hamnat rätt i sorteringsordningen eller blivit rot. Datastrukturer och algoritmer Borttagning ur en heap VT08 Ersätt noden som ska tas bort med den ”sista” noden i heapen. Låt denna vandra ned tills den hamnat ”rätt” eller nått ”botten”. Datastrukturer och algoritmer Animering VT08 Längst ned på sidan http://people.ksp.sk/~kuko/bak/big (välj Heap)