Översikt Linjär sökning Sökning Binär sökning Hashtabeller Programmering tillämpningar och datastrukturer 2 Linjär sökning Binärt sökträd Undersök ett element i taget tills du hittar det sökta Komplexitet Behöver i genomsnitt göra n/2 jämförelser om elementet är med Kan behöva göra n jämförelser om elementet inte är med Jfr med Sternbergs experiment med människor, där båda fallen blev n Programmering tillämpningar och datastrukturer Programmering tillämpningar och datastrukturer Sorterad array Binär sökning 1 2 6 8 9 12 Förutsätter sorterad sekvens, t.ex. balanserat sorterat binärt träd: 1. Jämför det sökta med mittenelementet (eller roten i trädet) 1. Om elementet är lika: klar 2. Om större än det sökta, sök vidare i första halvan av sekvensen (vänster delträd). Om mindre: sök vidare i andra halvan (höger delträd) 2. Avsluta om tomt Programmering tillämpningar och datastrukturer Programmering tillämpningar och datastrukturer 6 1
Komplexitet för binär sökning Eliminerar halva arrayen för varje rekursivt anrop (alltså log 2 n anrop) Gör log 2 n jämförelser, dvs. algoritmen växer logaritmiskt: O(log 2 n) Om obalanserat binärt träd, kan binär sökning i värsta fall degenerera till O(n) sökning! För sekvens med 00: O(n) = 00 jämförelser O(log 2 n) = jämförelser Arrays.binarySearch Kan anropas med sorterade arrays Det sökta måste vara av samma typ som elementen i arrayen Annars ClassCastException Om det finns dupplikat i arrayen, går inte att veta vilken av dessa som hittas Programmering tillämpningar och datastrukturer Programmering tillämpningar och datastrukturer 8 Hashtabeller Kan lagra <nyckel, värde>-par Nycklarna Måste vara unika Måste kunna omvandlas till hashkod Värdena behöver inte vara unika <T > <D > <S > <H > <P > hashkoder Hashning hashtabell Programmering tillämpningar och datastrukturer 9 Programmering tillämpningar och datastrukturer Omvandling till hashkod Ex. personnummer Första två siffrorna Summa av alla tio siffror Kodning enligt samma idé som decimala eller binära tal 2 = * 2 + 2* 1 + 2012-289 = *1 9 +2*1 8 + +9 1 primtal, minimerar risken att vi får samma index för olika personnummer Skalning av hashkod till index Hashkod inom intervallet [0 9*1 9 ] Tabellen är mycket mindre än detta Antag tabell med storlek size Då får vi index genom att dividera med size och ta remainder Ex. s.hashcode() % tabell.length(); Innebär att flera hashkoder hamnar på samma index Programmering tillämpningar och datastrukturer Programmering tillämpningar och datastrukturer 12 2
Exempel Hantering av kollisioner hashkod 82 2129869 Två strategier att lägga in element i hashtabellen Öppen adressering Hinkar ( buckets ) 6996 8 8289 2808 Programmering tillämpningar och datastrukturer 1 Programmering tillämpningar och datastrukturer 1 Öppen adressering Inläggning Kolla om tabell[index] upptagen Om ja, kolla tabell[index+1], etc. Sök tills ledig plats Uppslagning Kolla om sökta elementet ligger på index Om inte, kolla tabell[index+1] Sök tills -referens Denna plats hade varit ledig för elementet vid inläggning nyckeln blev aldrig inlagd Nackdelar Hur ta bort element? Kan inte skapa nya -referenser Detta skulle tolkas som slutet på en sökkedja = det sökta elementet finns inte i tabellen Alltså, vid borttagning: Ersätt med dummy-element Slösar med utrymme Fyller upp tabellen Skapar långa sökkedjor Programmering tillämpningar och datastrukturer 1 Programmering tillämpningar och datastrukturer 16 Programmering tillämpningar och datastrukturer 1 Programmering tillämpningar och datastrukturer 18
Programmering tillämpningar och datastrukturer 19 Programmering tillämpningar och datastrukturer 20 Belastningsnivå (load factor) Om tabellen full Oändlig (cirkulär) sökkedja, vet inte om varit här förut (finns inga referenser) Långa uppslagningstider load factor Vill hålla tabellen max % full Rehashing Allokera ny större tabell Insättning av alla gamla värden Ger jämn fördelning, istf en stor klump Programmering tillämpningar och datastrukturer 21 Programmering tillämpningar och datastrukturer 22 Hinkar (buckets) Buckets Vid kollision Länka in det nya elementet till de som redan finns där Buckets (länkade kedjor vid indexet) Fördelar Kan ha (nästan) full tabell Borttagna blir faktiskt borttagna Spar på minnet Programmering tillämpningar och datastrukturer 2 Programmering tillämpningar och datastrukturer 2
Söktid (öppen adressering) Söktid O(1) Men, ju fullare tabell, desto längre sökkedjor, desto längre söktid: O(n) Genomsnittlig sökning vid öppen adressering (L = load factor) 1 1 1+ 2 1 L Söktid (buckets) Hamnar direkt på rätt index Ska söka igenom en lista I genomsnitt halva listan Om snitt listlängden antas vara L/2, blir genomsnittliga söktiden 1+ L 2 Så, buckets bättre vid L > % Programmering tillämpningar och datastrukturer 2 Programmering tillämpningar och datastrukturer 26 pning mellan nycklar och värden Nycklarna måste vara unika Används för Uppslagstabeller Hashtabeller isempty() put(key, Value) get(object) remove(object) Protokoll för Programmering tillämpningar och datastrukturer 2 Programmering tillämpningar och datastrukturer 28 Protokoll för Hash Sorted Tree Concurrent ConcurrentHash «metaclass» Abstract Enum Properties Hash LinkedHash static final float DEFAULT_LOAD_FACTOR = 0.f; public Hash(int initialcapacity, float loadfactor) // konstr. V put(k key, V value) V remove(object key) V get(object key) // hämtning boolean containsvalue(object value) // sökning int size() boolean isempty() clear() Programmering tillämpningar och datastrukturer 29 Programmering tillämpningar och datastrukturer 0