Algoritmer og Datastrukturer 1 Hashing [CLRS, kapitel 11.1-11.4 ]
INF 295 Algoritmer og datastrukturer Forelesning 10 Invarianter og Hashing
description
Transcript of INF 295 Algoritmer og datastrukturer Forelesning 10 Invarianter og Hashing
INF 295 Algoritmer og datastrukturer
Forelesning 10 Invarianter og Hashing
Hans Fr. Nordhaug
(Ola Bø)
Invarianter
I mange algoritmer er det vilkår som forblir uforandret mens algoritmen kjøres
Slike vilkår kalles invarianter Det er nyttig å kjenne igjen invarianter for å forstå
algoritmen Invarianter kan også brukes under feilsøking For algoritmen som setter inn en ny node i et
søketre er invarianten vilkåret for søketrær, nemlig at for hver node skal alle noder i dens venstre subtre ha lavere verdi og alle noder i dens høyre subtre ha høyere verdi
Invarianter
Invarianten er ikke nødvendigvis sann for hver programsetning, men må stemme for hver gang programmet kommer til et gitt punkt.
Hash-tabell-ADT
Færre operasjoner enn binært søketre Hashing er en teknikk for innsetting, søking
og sletting i konstant tid Men findMin, findMax og printSorted støttes
ikke i lineær tid Hashtabell kan implementeres på ulike måter
Sammenlikning av implementeringer Vise applikasjoner Sammenlikning med binære søketrær
Hash-tabell Array med konstant størrelse Instansene vi søker etter lagres i tabellen Vanligvis blir søk basert på en eller flere
instansvariable Det vi søker på kalles nøkkel Eksempel:
Ansatt(Navn, Adresse, Fødselsnummer,Avd, Lønn,..) TableSize Fra nøkkelen beregnes et bestemt tall mellom 0
og TableSize-1. Dette tallet avgjør hvor instansen lagres
Beregningen er en funksjon - en hash-funksjon
Hash-funksjonen
Indeks=Hash(nøkkel) Bør være enkel (rask) å beregne Bør ideelt plassere instansene i hver sin celle
Vanskelig å oppnå Vi søker funksjoner som gir jevn spredning av nøklene
Hva vi må forholde oss til Hvordan velge hash-funksjonen Hva om to nøkler hashes til samme celle? Hvor stor bør Hash-tabellen være
Hash-funksjoner
Standard hash-funksjon - der nøkkel er heltall Velge primtall som TableSize Hashfunksjonen er resten i divisjonen av nøkkel med
TableSize. (nokkel%tableSize) Vanligvis er nøklene String
Addere ascii (Unicode) verdiene for tegnene og deretter finne resten - ubrukelig
Bruke bokstavverdiene som koeffisienter i et polynom og beregne verdien av polynomet for en gitt x Fungerer dårlig med bare de første bokstavene og x=27 Fungerer bra med alle bokstavene og x=29 Beregningen går fort med Horners regel
Hash-funksjoner
Java String sin Hash-funksjon
Kollisjonshåndtering med separat kjede
Lage liste over alle elementer som hasher til samme celle
Innsetting Finn nøkkel, Gjennomsøk lista, Duplikathåndtering Sett inn nye først - fordi sist innsatt ofte reaksesseres snart
Andre alternativer: trær, ny hash - brukes vanligvis ikke
Lastfaktor λ=elements/TableSize Gjennomsnittlig listelengde=lastfaktoren Regel: Ta sikte på lastfaktor=1 dvs:
TableSize=antatt antall elementer
Kollisjonshåndtering med åpen adressering
Ved kollisjon - prøv neste celle til du finner en ledig.
Hva er neste celle? Avhenger av søkestrategien f(i) hi(x)=(hash(x)+f(i))%TableSize
Alternativ til lenket liste: Kanskje raskere Enkelt med bare én datastruktur
Lastfaktoren må være mindre: λ<0.5
Søkestrategier ved åpen adressering Lineær søking
f(i) er en lineær funksjon. f. eks. f(i)=i Primær clustering av elementer kan føre til kostbare søk
Kvadratisk søking f(i) er en kvadratisk funksjon f. eks. f(i)=i2
Kan svikte totalt hvis λ>0.5 Må ha odde TableSize - ellers kan vi få svikt lenge før λ=0.5 Sekundær Clustering
Dobbel hashing F.eks f(i)=i*hash2(x) NB hash2(x) skal ikke kunne bli 0 Forslag: hash2(x)=R-(x mod R), der R er prim<TableSize
Dekning er viktig
Lineær versus kvadratisk søking
Mer om åpen adressering Sletteproblemet:
Kan ikke slette elementer Rehashing
Ved stor lastefaktor blir hashtabellen lite effektiv eller kan svikte helt (kvadratisk søk)
Løsning: Lag ny, minst dobbelt så stor tabell og hash alle elementene inn i den nye tabellen
Kostbar, men sjelden operasjon Problem hvis del av interaktivt system Når startes det?
Halvfull tabell ved kvadratisk søking Når innsetting mislykkes På en bestem lastefaktor
Anvendelser
Kompilatorer - symboltabeller Spill - transposisjonstabeller Stavekontroll I databaser
Konklusjon
Hashtabell er bedre enn søketre på finn og sett inn Ved mistanke om sorterte inndata bør du absolutt velge Hashtabell -
Hvorfor? Hashtabell er ubrukelig på traversering og findMin Viktige momenter for hashtabeller
Hashfunksjonen må gi god spredning og full dekning med de aktuelle nøklene
TableSize må være primtall Lastfaktoren λ er avgjørende for ytelsen Strategi for kollisjonshåndtering
Åpen adressering er svært følsom for λ og kan få clustering-problemer Kjedet implementering tåler høyere λ, men er kanskje mer komplisert