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)
tablica z haszowaniem T[0..m-1] wstawiamy zbiór kluczy K pochodzących ze zbioru możliwych kluczy U (z każdym kluczem związana jest pewna informacja) pseudolosowa funkcja haszująca h: U {0,1,..,m-1} idea: 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
funkcje haszujące - klucz jest liczbą haszowanie modularne h(k)= k%m - klucz nie jest liczbą generujemy liczbę na podstawie klucza i postępujemy jak poprzednio, np. k jest datą (d m r): h(d m r)=(d+m+r)%m k jest napisem abcde : h(abcde) = ( a + B( b + B( c +B( d + B e )))) % m gdzie B to pewna stała całkowita
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 0 1 18 36 9 10 2 3 4 5 12 41 14 6 7 8 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;
int szukaj(klucze k, info T[]){ int h,i,p; h=hash(k); i=0; // numer próby do{ p=(h+i)%m; if (T[p].klucz == k){ return p; } else i++; } while(t[p] nie jest wolne i i<m); 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