Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Algorytmy i struktury danych Tablice haszowane. Klucz Klucz – wyróżnik danych np. data ur.+imię +nazwisko, pesel, nr dowodu, nr indeksu Założymy, że klucze.

Podobne prezentacje


Prezentacja na temat: "Algorytmy i struktury danych Tablice haszowane. Klucz Klucz – wyróżnik danych np. data ur.+imię +nazwisko, pesel, nr dowodu, nr indeksu Założymy, że klucze."— Zapis prezentacji:

1 Algorytmy i struktury danych Tablice haszowane

2 Klucz Klucz – wyróżnik danych np. data ur.+imię +nazwisko, pesel, nr dowodu, nr indeksu Założymy, że klucze to liczby, zawsze można zbudować funkcję transformującą np. napis na liczbę: Można np. zsumować kody odpowiadające literom ALA ->

3 Tablica z adresowaniem bezpośrednim K T Klucz Dane Klucz Dane Klucz Dane Klucz Dane ! Małe uniwersum kluczy !

4 Adresowanie bezpośrednie - implementacja def DirectAdress_Search(table, key): return table[key] def DirectAdress_Insert(table, x): table[x.key] = x def DirectAdress_Delete(table, key): table[key] = None

5 Tablica z funkcją haszującą k5k5 k8k8 k3k3 K Klucz Dane Klucz Dane Klucz Dane Klucz Dane k2k2 Funkcja haszująca odwzorowuje klucz w przestrzeń adresową tablicy Uniwersum wszystkich kluczy

6 Funkcja haszująca F. haszująca - odwzorowuje klucz w przestrzeń adresową (zwykle mniejszą niż uniwersum), tj. dziedzinę poprawnych adresów tablicy h(k) powinno należeć do przestrzeni adresowej tablicy dla dowolnego (legalnego) klucza Wymagania: generowanie adresów dla rzeczywistego zbioru rekordów w sposób jak najbardziej równomierny (rozproszony) łatwość obliczenia Wskazane jest sprawdzenie wybranej f. haszująca na fragmencie rzeczywistych danych

7 Haszowanie modularne h(k) = k mod m, gdzie m jest rozmiarem tablicy Dobre m nie powinno być równe 2 p, 10 p – gdyż takie haszowanie ignoruje bardzo znaczące bity (cyfry) Dobre m nie powinno być równe 2 p -1, 10 p -1 gdyż daje identyczne wartości na ciągach, dla których przestawiono bity (cyfry) Niezłe są np. liczby pierwsze niezbyt bliskie potęgom 2

8 Haszowanie przez mnożenie h(k) = m (kA mod 1), gdzie kA mod 1 = kA A zwykle jest liczbą z przedziału 0..1 m jest zwykle potęgą 2 lub 10, gdyż wtedy h(k) = pewna ilość cyfr po przecinku z kA W praktyce bardzo dobre A to np. (sqrt(5)-1)/2 =

9 Haszowanie przez randomizację h(k) = Rand (k) Metoda kwadratu środka: wydziel z klucza pewną jego część (np. środek), potraktuj jako liczbę binarną, po czym podnieś ją do kwadratu. Metoda składania: podziel klucz na części (segmenty), potraktuj je jako liczby binarne, po czym dodaj je do siebie arytmetycznie. Metoda sumy modulo 2: podziel klucz na części (segmenty), potraktuj je jako ciągi bitów i dodaj je do siebie modulo 2. W praktyce dla uzyskania dobrej losowości wymagane sa duże wartości stad często stosuje się ta metode w połączeniu z h. modularnym

10 Haszowanie uniwersalne H – rodzina funkcji haszujących Na początku pracy losowo wybieramy jedną funkcję haszującą z całej rodziny i stosujemy ją od tej pory h H Brak możliwości złośliwego doboru elementów

11 Rozwiązywanie kolizji przez łańcuchowanie oddzielne Listy zawierają elementy, dla których h(k) jest takie samo-synon. Kolejność elementów na liście jest przypadkowa k5k5 k8k8 k3k3 k2k2 Dane k2k2 k12k12 k 12 Dane k15k15 k3k3 k 15 Dane k5k5 k8k8 9 h(k) = k mod 10

12 Łańcuchowanie oddzielne – impl. def ChainHash_Search(table, key): return FindInList(table[h(key)], key) def ChainHash_Insert(table, x): pos = h(x.key) table[pos] = AddHead(table[pos],x) def ChainHash_Delete(table, key): pos = h(x.key) table[pos] = DeleteFromList(table[pos],key)

13 Łańcuchowanie oddzielne - właściwości - współczynnik zapełnienia = ilość elementów / rozmiar tablicy Pesymistyczny czas wyszukiwania = (n) Jeżeli h rozmieszcza klucze równomiernie, to dla Oczekiwany czas wyszukiwania = (1+ )

14 Rozwiązywanie kolizji przez łańcuchowanie bezpośrednie Listy tworzone są w obszarze tablicy W przypadku dodawania nowego elementy do listy wybierana jest pierwasza wolna komórka k5k5 k8k8 k3k3 K k2k2 Dane k2k2 k12k12 k 12 Dane k15k15 k3k3 k 15 Dane k5k5 k8k8

15 Adresowanie otwarte Dla rozwiązywania konfliktów nie stosuje się list Wszystkie elementy (wskaźniki) zapisywane są bezpośrednio w tablicy h(k, i) = (h(k) + g(i)) gdzie: k – klucz, i – numer próby (0..N-1), N – rozmiar tablicy Aby umieścić element w tablicy sprawdzamy h(k, 0) jeśli zajęte, to h(k, 1) itd aż do h(k, N-1).

16 Adresowanie otwarte przykład kolizji Kolejność dodawania: k 12, k 2, k 4, k 3 k3k3 h(k) = (k+i) mod 10 k2k2 Dane k2k2 k12k12 k4k4 k 12 Dane k4k4 k3k3

17 Adresowanie otwarte – implem. def Hash_Insert(table, x): for i in range(i, MAX): j = h(x.key, i) if table[j] == None: table[j] = x return ERROR przepełnienie tablicy

18 Adresowanie otwarte – implem. def Hash_Search(table, key): for in range(0, MAX): j = h(key, i) if table[j] == None: return None if table[j].key == key: return table[j] return None

19 Adresowanie otwarte – usuwanie elementów Problem: Nie można wpisywać None Rozwiązanie: Nowa stała np.: DELETED Należy wtedy zmodyfikować przeszukiwanie if table[j] == None: return None if table[j] == DELETED: continue if table[j].key == key: return table[j] i dodawanie if table[j] == None or table[j] == DELETED:

20 Rodzaje adresowania otwartego Liniowe: h(k,i) = (h(k) + i ) mod m Wadą jest grupowanie się elementów Kwadratowe: h(k,i) = (h(k) + c 1 i + c 2 i 2 ) mod m Wadą jest (mniej groźne) grupowanie wtórne Sześcienne: h(k,i) = (h(k) + c 1 i + c 2 i 2 + c 3 i 3 ) mod m Wadą jest (mniej groźne) grupowanie wtórne Dwukrotne: h(k,i) = (h 1 (k) + h 2 (i)) mod m Grupowanie wtórne jest znikome

21 Metoda otwarta - właściwości - współczynnik zapełnienia = ilość elementów / rozmiar tablicy Pesymistyczny czas wyszukiwania = (n) Dla liniowej funkcji g oczekiwany czas wyszukiwania z sukcesem 1+1/(1- ) z porażką to 1+1/(1- ) 2 Dla pseudolosowej funkcji g oczekiwany czas wyszuk. z sukcesem -1 (1+ln (1/(1- ))) z porażką to 1/(1- )

22 Uniwersum kluczy Powinno być nie mniejsze niż rozmiar tablicy Sumowanie kodów liter np. ALA -> Stosunkowo mały rozmiar uniwersum, np. dla 30 znaków 30*256 = 7680 Sumowanie par (lub dłuższych ciągów liter), co daje większą przestrzeń adresów ALA -> 65* *256 W uniwersum są dziury bo np. znaki mają kody >=32 i zwykle mniejsze niż 127 Suma iloczynów kodów par ALA -> 65* Nierównomierny rozkład wartości, np. więcej l. parzystych

23 Przykład Tablica 10 6 elementów adresowana nazwiskiem i imieniem Znaki: W ogólności jeden znak dla ASCII znaki niedrukowalne, 32-47, 91-96, znaczki różne, cyfry, 65-90, – litery, znaki graficzne (polskie litery) UNICODE – jeden znak 0 – ( ), dużo bardzo rzadko używanych znaków. Przy obliczeniach można pominąć znaki różne od liter (ewentualnie cyfr) Polskie znaki diakrytyczne: można zamienić na ich łacińskie odpowiedniki lub pominąć. Zamieniamy znaki na małe. Stąd jeden znak może mieć kod od 97 do 122. log = log = Czyli maksymalna waga dla znaku powinna wynosić co najmniej 26 5.

24 Przykład MAXP = 5 BASE = ord("Z")-ord("A")+1 def K(key): for c in key: c = Convert(c) # konwersja na duze litery + # ew zamiana polskich znaków if c>="A" and c<="Z": digit = ord(c)–ord("A") keyVal = keyVal + digit * pow(BASE, p) p = (p+1) % (MAXP+1) return keyVal


Pobierz ppt "Algorytmy i struktury danych Tablice haszowane. Klucz Klucz – wyróżnik danych np. data ur.+imię +nazwisko, pesel, nr dowodu, nr indeksu Założymy, że klucze."

Podobne prezentacje


Reklamy Google