szukaj w
Transkrypt
szukaj w
struktury danych dla operacji słownikowych • tablica nieuporządkowana • tablica uporządkowana • lista dowiązaniowa • drzewo poszukiwań binarnych • drzewa zrównoważone • z tablice haszowaniem tablice z haszowaniem (tablice mieszań) (hash table) T[0..m-1] wstawiamy zbiór kluczy K pochodzących ze zbioru możliwych kluczy U tablica z haszowaniem (z każdym kluczem związana jest pewna informacja) pseudolosowa funkcja haszująca idea: h: U ➞ {0,1,..,m-1} klucz k zapiszemy na pozycji h(k) w tablcy T k ➞ T[h(k)] problem kolizji: k1 ≠ k2 ale f(k1) = f(k2) czyli dwa różne klucze przypadają na tę samą pozycję w tablicy są różne metody rozwiązywania problemu kolizji Metoda łańcuchowa rozwiązywania kolizji W każdej pozycji tablicy T[i] jest początek listy tych kluczy 0 1 2 3 4 5 6 7 8 k dla których h(k)=i ➞18➞36➞9 ➞10 ➞13 ➞41➞14 ➞8 Metoda łańcuchowa rozwiązywania kolizji W każdej pozycji tablicy T[i] jest początek listy tych kluczy k dla których h(k)=i wstaw klucz k do tablicy T: wstaw k do listy T[h(k)] szukaj klucza k w tablicy T: szukaj k na liście T[h(k)] usuń klucz k z tablicy T: usuń k z listy T[h(k)] Metoda łańcuchowa rozwiązywania kolizji Pesymistyczna złożoność czasowa operacji na tablicy z haszowaniem rozmiaru m, w której znajduje się n kluczy, z rozwiązywaniem konfliktów metodą łańcuchową: - wstaw, usuń: Θ(1) - szukaj: Θ(n) Metoda łańcuchowa rozwiązywania kolizji Średnia złożoność czasowa operacji szukaj w tablicy z haszowaniem rozmiaru m, w której znajduje się n kluczy, przy założeniu o równomiernym haszowaniu: O(1+n/m) Wniosek. Jeżeli n ≤ c·m gdzie c to jakaś stała, to złożoność czasowa operacji szukaj w tablicy z haszowaniem, przy założeniu o równomiernym haszowaniu: jest O(1) Metoda łańcuchowa rozwiązywania kolizji Założenie o równomiernym haszowaniu: dla losowo wybranego klucza k, wartość h(k) z jednakowym prawdopodobieństwem trafia w każdą z pozycji 0,1,2, ... ,m-1 Rozwązywanie problemu kolizji przez adresowanie otwarte wariant: adresowanie liniowe Jeżeli pozycja tablicy T[h(k)] jest zajęta przez inny klucz, to dla klucza k szukamy wolnej pozycji na kolejnych pozycjach: (h(k)+i)%m dla i = 1,2, ... gdzie x%m oznacza resztę z dzielenia x przez m adresowanie liniowe zatem, dla klucza k generujemy ciąg pozycji H(k,i) = (h(k)+i)%m dla i = 0,1,2, ... gdzie x%m oznacza resztę z dzielenia x przez m i próbujemy wstawić klucz k na tych pozycjach H(k,0), H(k,1), H(k,2), ... adresowanie liniowe 0 1 2 3 4 5 6 7 8 16 17 m=9 h(k) = k%m wstaw 25: h(25) = 25%9 = 7 H(25,0) = (h(25)+0)%9 = (7+0)%9 = 7 H(25,1) = (h(25)+1)%9 = (7+1)%9 = 8 H(25,2) = (h(25)+2)%9 = (7+2)%9 = 0 int wstaw(info x, info T[]){ int h,i,p; h=hash(x.klucz); i=0; // numer próby do{ p=(h+i)%M; if (T[p] jest wolne){ T[p]=x; return p; } else i++; } while(i<M); printf("przepelnienie\n"); return -1; adresowanie otwarte Pesymistyczna złożoność czasowa operacji na tablicy z haszowaniem rozmiaru m, w której znajduje się n kluczy, z rozwiązywaniem konfliktów metodą adresowania otwartego: - wstaw, szukaj: Θ(n) - usuń: Θ(1) adresowanie otwarte Średnia złożoność czasowa operacji szukaj w tablicy z haszowaniem rozmiaru m, w której znajduje się n kluczy, z użyciem adresowania otwarego, przy założeniu o równomiernym haszowaniu: O(1/(1-α)), gdzie α = n/m. Wniosek. Jeżeli α ≤ c < 1 gdzie c to jakaś stała, to złożoność czasowa operacji szukaj w tablicy z haszowaniem, przy założeniu o równomiernym haszowaniu: jest O(1). adresowanie otwarte Założenie o równomiernym haszowaniu: dla losowo wybranego klucza k, ciąg wartości H(k,0), H(k,1), ... ,H(k,m-1) z jednakowym prawdopodobieństwem daje każdą z permutacji liczb 0,1,2, ... ,m-1