• No results found

Datastrukturer och algoritmer. Innehåll. Trie. Informell specifikation. Organisation av Trie. Föreläsning 13 Trie och Sökträd.

N/A
N/A
Protected

Academic year: 2022

Share "Datastrukturer och algoritmer. Innehåll. Trie. Informell specifikation. Organisation av Trie. Föreläsning 13 Trie och Sökträd."

Copied!
6
0
0

Loading.... (view fulltext now)

Full text

(1)

Datastrukturer och algoritmer

Föreläsning 13 Trie och Sökträd

Innehåll

• Trådar

• Trie

• Sökträd

3

Trie

• Ytterligare en variant av träd. Vi har tidigare sett:

– Oordnat träd där barnen till en nod bildar en mängd

– Ordnat träd där barnen till en nod bildar en lista

• I Trie är barnen till en nod organiserade som värden i en tabell som hör till noden

• Trie kallas också diskrimineringsträd, code-

link tree eller radix-search tree.

4

Organisation av Trie

• Barnen (delträden) nås direkt genom ’namn’, dvs argument/nycklar i barnnodens tabell

– Nycklarna brukar skrivas direkt intill motsvarande båge

• I en Trie har tabellerna en och samma nyckeltyp, t.ex. tecken

• I många tillämpningar av Trie saknar de inre noderna etiketter, träden är lövträd

• Trie är normalt nedåtriktade

• Binära träd kan ses som ett specialfall av Trie där ntyckelvärdena är ’left’ och ’right’

5

Informell specifikation

• Två sätt:

– Utgå från Urträdets specifikation och låt typparametern sibling ha värdet Tabell.

• Då hanteras insättning, borttagning och värdekoll av Tabellen själv.

• I övrigt används de vanliga operationerna för att sätta in och ta bort barn etc.

– Sätt in lämpliga tabelloperationer direkt i specifikationen av Trie

• Insert-child blir tabellens insert, delete-child tabellens remove och Child tabellens lookup

6

(2)

Konstruktion av Trie

• De flesta konstruktioner av träd går bra att använda

– Om det går att byta ut de delar som hanterar barnen (t.ex som element i en lista) till att hantera dessa som tabellvärden

• En länkad lista med 2-celler byts till 3-celler

– Implementerar man tabellen som en vektor eller som en hashtabell får man effektiva

Trieimplementationer

7

Tillämpningar med Trie

• Används för att konstruera lexikon av sekvenser eller Tabeller där nycklarna är sekvenser

• För sekvenser med element av typ A väljer vi en Trie med tabellnycklar av typ A.

– En sekvens motsvaras då av en väg i trädet från roten till ett löv

– Man lägger en slutmarkör i slutet av varje sekvens om en sekvens kan vara början på en annan

• En annan variant är att ha etiketter i de inre noderna också

• Ett viktigt/vanligt specialfall är lexikon/Tabell av textsträng. En sträng kan ju ses som en lista eller vektor av tecken.

8

Forts ...

• Fördelar med att använda Trie för

Lexikon/Tabeller som lagrar sekvenser som startar med samma följd av elementvärden:

– Kompakt sätt att lagra lexikonet/tabellen – Sökningens tidskomplexitet proportionell mot

sekvenslängden (en jämförelse per tecken)

– Den relativa kompelxiteten är oberoenda av storleken på lexikonet/tabellen

Det blir inte ”dyrare” att söka i ett stort lexikon jämfört med ett litet

9

Exempel

10

Bild från sidan 284 i Janlert L-E., Wiberg T., Datatyper och algoritmer, Studentlitteratur, 2000

Tillämpningar

• Stavningskontroll

– Skapa trie med alla ord som finns i språket

• Övesättningstabell

– Löven innehåller motsvarande ord i ett annat språk

• Filsystem på Unix/PC

• Datakomprimering

– LZ78-algoritmen - zip, gzip, png bland annat – Huffman-kodning

11

LZ78 eller Lempel-Ziv kodning

• Kodning:

– Låt frasen 0 vara den tomma strängen ””

– Gå igenom texten

• Om du stöter på en ’ny’ bokstav lägg till den på toppnivån i trien

• Om du stöter på en ’gammal’ bokstav gå nedåt i trien tills du inte kan matcha fler tecken, lägg till en nod i trien som representerar nya strängen

• Stoppa in paret (nodeindex, sistaBokstaven) i den komprimerade strängen

12

(3)

How now brown cow in town.

13

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0

2 3 4 5

6 7

8

9

10 11

12 13

14

15 1

h o w _ n r i t

w b c _

n _

. 0h 0o 0w 0_ 0n 2w 4b 0r 6n 4c 6_ 0i 5_ 0t 9.

how now brown cow in town.

LZ78 eller Lempel-Ziv kodning

• Avkodning:

– Varje gång du stöter på ”0” (noll) i den komprimerade strängen lägg nästa bokstav direkt efter den föregående i resultatsträngen

– För varje index != 0 stoppa in delsträngen som motsvaras av noden (med detta index) i resultatsträngen, följt av nästa tecken i den komprimerade strängen

– Notera att man inte behöver skicka med trädet om man bygger upp det allt eftersom i avkodningen

• Exempel:

0h 0o 0w 0_ 0n 2w 4b 0r 6n 4c 6_ 0i 5_ 0t 9.

14

h o w n ow b r own c ow i n t own.

Filkomprimering på ett annat sätt

• ASCII-filer är textfiler där varje bokstav representeras av en 8-bitars kod

– Det är alltås en fixlängdskodning

• Om man tittar på en textfil ser man att vissa bokstäver förkeommer oftare än andra

– E är vanligast i engelska – jm Morse-alfabetet

• Om man lagrar vanligt förekommande tecken med färre bitar så skulle vi kunna spara plats

15

Filkomprimering

• Kodningen måste ske så att att man enkelt kan avkoda strängen entydigt med

kännedom om hur de olika tecknen översätts

– Exempel: Antag att de tre tecknen a, b och c kodas som 0, 1, resp 01.

• Om en mottagare får strängen 001 vad betyder det ? aab eller ac ?

• Prefix-regeln: Ingen symbol kodas med en sträng som utgör prefix till en annan symbols kodsträng

16

Vi använder ett trie !

• Bokstäverna lagras i löven

• Den vänstra kanten betyder 0

• Den högra betyder 1

17

Vad betyder

01011011010000101001011011010 ? 010 11 011 010 00 010 10 010 11 011 010 A B R A C A D A B R A

Vi vill ha optimal komprimering

• Så kort sträng som möjligt. Strängen

01011011010000101001011011010 = 29 bitar kan kortas ned till 24 bitar (23 bitar som mest):

001011000100001100101100 med trädet

• Bland annat har A fått kortare kod och C längre

18

(4)

Huffman-kodning

• Börja med en serie träd bestående av ett endal löv. Till varje löv associeras en symbol och en vikt = symbolens frekvens i texten som skall kodas

• Väl de två träd som har minst vikt i roten.

Bygg ihop dem till ett nytt träd där de blir barn till en ny nod. Den nya noden innehåller en vikt = summan av barnens vikter.

• Upprepa detta till vi har ett enda stort träd

• Jpeg, mp3

19

Huffman - ABRACADABRA

• ABRACADABRA

20

A 5/11 B

2/11 R 2/11 C

1/11 D 1/11

C 1/11 D

1/11 2/11 2/11 B R

2/11 4/11

6/11 5/11 A

11/11 ABRACADABRA blir nu 23 bitar 0 100 101 0 110 0 111 0 100 101 0

Tries för strängar

• Insättning

– Startar i roten och går nedåt i trädet så länge det finns en matchande väg

– När man hittar en skiljelinje, stanna och stoppa in resten av strängen som ett delträd

– Komprimerade tries:

• Liknande algoritm men där är löven strängar som kanske måste delas upp i två barn senare

• Borttagning

– I princip samma algoritm som insättning fast tvärtom. Sök upp strängen som ska tas bort och radera nerifrån i trädet upp till första förgreningen

21

Komprimerade tries

• Alla enbarnsnoder konverteras till att innehålla hela strängen/sekvensen som ligger under

22

o

t

ot

Binärt sökträd

• Används för sökning i linjära samlingar av dataobjekt, specifikt för att konstruera tabeller och lexikon

• Organisation:

– Ett binärt träd som är sorterat med avseende på en sorteringsordning R av etikett-typen 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

23

Informell specifikation

• Skiljer sig från ett vanligt binärt träd:

– Alla noder måste ha etiketter

• Ta bort create, Has-Label och Set-label och inför Make som skapar rotnod med värde

• Insert-operationerna utökas med ett etikettvärde – Det skall gå att ta bort inre noder, inte bara löv

• Positionsparametern i delete-node behöver inte peka på ett löv

• När man tar bort en inre nod trasas trädet sönder. Hur lagar man det ?

– Är nedåtriktat

• Parent kan utelämnas

– Eftersom trädet är sorterat kan man inte stoppa in ett nytt element var som helst

• Måste uppfylla sorteringsordningen 24

(5)

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 nedåt rekursivt i vänster eller höger delträd beroende på sorteringsordningen

• Om det binära trädet är komplett:

– Värstafallskomplexiteten för sökning är O(log(n)) för ett träd med n noder – Hur ser man till att trädet blir komplett vid

insättning ? (vi tittar på det senare)

25

Borttagning av nod i binärt sökträd

• Hur lagar man ett träd när man tagit bort en inre nod ?

– Om den inre noden bara hade ett delträd

• Lyft upp det ett steg

– Om den borttagna noden hade två delträd:

• 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, det är upp till den som implementerar att välja

– De vanligaste tillämpningarna är inte beroende av denna detalj

– Viktigt att man visar sitt beslut i specifikation och

dokumentation 26

Exempel

• Vi har trädet

27

R B

N

T

S Y

C U

Exempel

• Ta bort element B. Det har bara ett delträd, lyft upp det:

28

R

N T

S Y

U C

Exempel

• Ta bort R, alternativ 1

29

S B

N

T Y C U

Exempel

• Ta bort R, alternativ 2

30

N B

C

T

S Y

U

(6)

Varför inte ändra gränsytan ?

• 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.

– Placa implementerar man i huvudsak med hjälp av andra metoder i gränsytan vilker är lite märkligt

– Strukturen döljs (för oss) och blir mer lik en mängd

31

Tillämpningar av Binärt sökträd

• Framförallt 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

32

Generaliseringar

• Ett binärt sökträd underlättar sökning i en- dimensionell datamängd

• Lätt att generalisera detta till sökning i en 2-dimensionell datamängd (quadtree) eller så hög dimension man önskar (t.ex octtree)

33

Quadtree (fyrträd)

• Organiserat som ett binärt träd med förgreningsfaktor 4 i stället för 2

• Tolkning (vanligast):

– Rotnoden delar in den givna ytan (oftast en kvadrat) i fyra lika stora kvadrater. Vart och ett av de fyra barnen delar i sin tur sin kvadrat i 4 osv. Inga koordinater behöver lagras i inre noder

• Kan användas för att lagra lägesinformation för punktformiga grafiska objekt

34

Quadtree – forts.

• Man kan också använda det för att representera kurvor och ytor

– Svarta kvadranter – fylls helt av objektet – Grå kvadranter – fylls delvis

– Vita kvadranter – innehåller inte objektet

• Exempel på tilläpning

– GIS

– Grafik – för att representera många små objekt som är ojämt spridda. Inga delträd för de kvadranter som är tomma sparar minne

35

References

Related documents

Ada Andersson, Bo Eriksson, Lars Andersson, Lena Andersson Om vi vill sortera efter efternamn istället, men samtidigt bibehålla ordningen mellan förnamnen så måste vi använda en

Gå igenom listan, och för varje anställd så adderar man du personens lön till det skrivna talet. När man nått slutet på listan så är det ned skrivna

4ndrar ett pagdende program, skall man avbryta maskinen genom att vrida termostatknappen till stallning

Uppgift: Sök upp givet element i en följd av element. Lösning: Gå igenom elementen i tur och ordning, kontrollera för varje element om det är det sökta. Avbryt om det

Vänster och höger delträd är sökträd och alla element i vänstra delträdet <.. elementet i

I kommande föreläsningar kommer vi att bekanta oss med släktträd som kan byggas med en enda pekare i varje post (faderspekaren). Med två pekare i varje post kan man emellertid

Ett binärt träd är antingen tomt eller så har rotnoden 2 underträd (subtree) som också är binära träd (vänster och höger underträd)... Binärt

• För att programmet ska kunna reagera på händelser kopplar man på olika typer av lyssnare till komponenter i fönstret. • Lyssnarna kan fånga upp händelser som