lgoritmer och datastrukturer 01, fo rela sning 8 Komplexitet för binära sökträd De viktigaste operationerna på binära sökträd är insert, find och remove Tiden det tar att utföra en operation bestäms till stor del av hur många noder som man behöver besöka innan man hittar rätt i trädet Naturligtvis går det mycket snabbare om vi har ett så platt träd som möjligt Det sämsta som kan inträffa är att sökträdet degenererar till en lista Detta kan hända om man lägger till data som redan är sorterat efter nyckeln Om trädet är bra balanserat så blir komplexiteten O(log n) och om det har degenererat till en lista blir komplexiteten O(n) VL-träd I så kallade VL-träd så ändrar man i träden om de börjar bli obalanserade Man säger att ett träd är balanserat om skillnaden i höjd mellan vänster och höger underträd är maximalt 1 för alla noder i trädet Höjden av ett null-träd sätter man till -1 Exempel I trädet till vänster så gör det vänstra barnet till roten att det inte är balanserat Höjden på dess vänstra underträd är 1 och höjden på höger underträd (som är ett null-träd ) är -1, så skillnaden är dvs större än 1 Detta träd är balanserat! Kolla själv att alla noderna har underträd som uppfyller villkoret Detta träd är inte balanserat Inget av rotens barn uppfyller villkoret Man kan visa att i ett VL-träd så är höjden ungefär 1,44*log n där n är antalet noder i trädet När man lägger till eller tar bort noder så finns ju alltid risken att trädet blir
obalanserat För VL-träd finns det operationer som rebalanserar träd Hur detta går till visas i figurerna nedan Vi börjar med detta träd Underträden, och har samma höjd men eftersom noden finns mellan roten och och så ligger och djupare än Efter en insättning av en nod så ökar djupet hos med 1 Detta medför att trädet blir obalanserat Observera att ordningen mellan noderna i trädet är <<<< När vi ändrar trädet så att det blir balanserat så måste denna ordning fortfarande gälla, annars har vi inte längre ett binärt sökträd! Här är vi flyttat om i trädet så att det är balanserat och så att ordningen fortfarande stämmer Detta sätt att flytta om noderna fungerar inte om man i stället lägger till en nod i underträd så att trädet blir obalanserat Då måste vi göra på ett annat sätt Det visas på figurerna nedan:
Vi börjar med samma träd som i exemplet ovan Nu stoppar vi dock in en nod i underträd så att det blir för djupt Då fungerar rebalanseringen i exempelt ovan inte, prova själv! För att kunna rebalansera trädet så ritar vi det så att man ser den översta noden i underträd Det finns ju minst en nod där eftersom vi ju faktiskt stoppade in en nod i det underträdet! Z 1 Z Därefter placerar vi nod Z överst och arrangerar om de andra noderna och underträden så att ordningen i trädet fortfarande är bevarad 1 Interfacet Map Ofta behöver man koppla ihop två värden med varandra I matematiken använder man funktioner eller som det ibland kallas avbilidningar (eng map) för att göra detta ntag att vi har två mängder Den ena mängden(kalla den ) innehåller nycklar (keys) och den andra mängden (kalla den ) innehåller värden (values) Om vi drar pilar från alla elementen i till precis ett element i så säger vi att vi har en avbildning eller funktion från till Det kan till exempel se ut som i följande figur:
1 3 c b a d Det gör ingenting att två pilar går till samma element i - mängden Det gör heller ingenting att det finns element i -mängden till vilka det inte går några pilar Det som däremot inte får förekomma är att det går två pilar från ett element i -mängden till två olika element i -mängden För att kunna beskriva avbildningar finns det ett interface i Java som kallas Map Det ser ut så här: public interface Map<K,V>{ boolean containskey(k key); //Finns key? V get (K key); V put(k key, V value); V remove(k key); int size(); // Här finns fler metoder! } Ett exempel på en klass som implementerar detta interface är TreeMap Man kan använda denna klass på följande sätt: TreeMap<Integer, String> reg = new TreeMap<Integer, String>(); regput(1345, Nisse ); regput(3456, nnika ); String name = regget(1345); if (name!= null) Systemoutprintln(name); TreeMap implementeras av en slags binära sökträd som kallas röd-svarta träd Varje nod är färgad med röd eller svart färg och det finns tre regler som måst uppfyllas för att det ska vara ett röd-svart träd: 1 Roten är svart Om en nod är röd så är alla dess barn svarta 3 Varje väg från roten till en null-länk ska innehålla samma antal svarta noder Om ett träd uppfyller reglerna så är det relativt väl balanserat Om någon regel inte följs efter insättning så måste man ändra i trädet så att reglerna följs igen Detta görs genom att både färga om noder och bygga om trädet
Generaliserade sökträd Man kan låta noderna i ett sökträd ha mer än ett barn Det ger grundare träd så att man inte behöver söka så länge innan man hittar en nod Läsanvisningar i nya boken 71-7, Läsanvisningar i gamla boken 193, 194, 195 (bara det före avsnitt 1951), 68, http://downloadoraclecom/javase/14/docs/api/java/util/dictionaryhtml