Sunteți pe pagina 1din 10

TABELE DE DISPERSIE

1. Structura de date de tip tabela de dispersie


Cel mai eficient algoritm de cutare este acela n care fiecrei valori
din colecia de elemente i se asociaz o poziie unic n cadrul mulimii.
Astfel, pe baza valorii cutate se determin poziia acesteia n cadrul
coleciei.
n cadrul vectorilor, aceast abordare se implementeaz cu uurin
deoarece asocierea dintre valoarea unei chei numerice ntreag i poziia
acesteia n vector se realizeaz prin:
- definirea unui vector cu numr de elemente egal cu valoarea
maxim posibil a cheii de cutare;
- se stabilete o valoare neutilizat n cadrul problemei de rezolvat
pentru a indica dac elementul cu cheia cutat exist deoarece
vectorul reprezint o zon de memorie continu, se
implementeaz principiul conform cruia elementele exist sau
sunt terse logic; pentru o cheie de cutare ce ia valori n
intervalul [0255],
valoarea -1 este fi utilizat pentru a indic inexistena elementului
cutat n colecie.
Principalul avantaj al cutrii bazate pe acces direct este dat de
rapiditate cu care se gsete elementul cutat sau este indicat inexistena
acestuia.
Cu toate acestea, n practic este evitat aceast soluie direct care,
dei minimizeaz timpul de regsirea prezint numeroase dezavantaje
generate de:
- dimensiunea memoriei ocupate spaiul de memorie, MEMORIE,
necesar implementrii acestei structuri este dat de relaia
MEMORIE = maxim(valoare cheie cutare) * dimensiune(element)

(17.1)

iar n cazul n care valoarea maxim este foarte mare atunci


trebuie s fie rezervat un spaiu considerabil;
gradului de utilizare a spaiului deoarece dimensiunea structurii
este dependent de valoarea maxim a cheii de cutare, nu se
ine cont de numrul real de elemente utilizate; cea mai
nefavorabil situaie este dat de un raport foarte mic dintre
numrul de elemente i valoarea maxim a cheii;
pentru a minimiza timpul de regsire, se implementeaz o
structur cu acces direct n care numrul matricol al studentului
este egal cu poziia n cadrul coleciei a respectivului element; n
cazul n care valoarea maxim a cmpului nrMatricol este egal
55630, iar numrul real de studeni este egal cu 1450 rezult un
spaiu ocupat egal cu:

MEMORIE=max(nrMatricol)*dimensiune(Student)=55630*48=2,54 MB
(17.2)

iar gradul de utilizare a acestui spaiu este egal cu:


GUM =

MEM

elemente

MEM

*100 = 1450 * 48

*100 = 2,6% (17.3)

55630 * 48

tipului cheii de cutare acesta trebuie s aib un tip numeric


ntreg deoarece trebuie s corespund indexului cu care se
acceseaz elementele unui vector.
Pentru a remedia dezavantajele utilizrii structurilor cu acces direct
sunt definite tabelele de dispersie, hash tables, ce reprezint colecii de
date n care pe baza unei funcii hash cheia de cutare este pus n
coresponden cu poziia elementului n cadrul coleciei. Avantajul acestei
tip de structur de stocare i cutare este dat de:
- utilizarea mai eficient a spaiului fr a se stoca memorie pentru
elemente care nu sunt utilizate n cazul aplicaiei de gestiune a
studenilor se observ c din totalul de 55630 de elemente, doar
1450 sunt utilizate; faptul se datoreaz concentrrii valorilor cheii
de cutare n intervalul [54130, 55630]; reducerea spaiului
ocupat de tabela de dispersie se realizeaz n aceast situaie prin
implementarea unei funcii hash: [54130, 55630] [0, 1500]
care s reduc valoarea maxim a cheii de cutarea prin
conversia valorii din intervalul [54130, 55630] ntr-o valoare din
intervalul [0, 1500]; o astfel de funcie hash cu un nivel de
complexitate sczut este
-

hash(X) = X modulo 1500, cu X

54130,55630

(17.4)

implementarea de chei alfanumerice prin utilizarea unei funcii


care s prelucreze cheia de cutare este depit bariera care
limita pentru structurile cu acces direct tipul cheii de cutare la o
valoare numeric ntreag; n aceast situaie rolul funciei hash
este de a translata valoarea alfanumeric ntr-o valoare ntreag
pozitiv; de exemplu, n limbajul Java este implementat funcia
hash pentru un string

hash(S) = s[0]*31n-1+s[1]*31n-2++s[n-2]*31+s[n-1]

(17.5)

unde:
s[i] codul ASCII al caracterului i din
ir; n dimensiunea irului de caractere.
Pentru cheia alfanumeric cu valoarea salut aplicarea funciei hash
conduce la obinerea valorii
hash(salut)=115*314+97*313+108*312+117*31+116=109202173 (17.6)

valoarea obinut este introdus din nou ntr-o funcie hash care s
identifice poziia corespondent din mulime pentru aceast valoare
numeric foarte mare.
Dezavantajul tabelelor de dispersie n cadrul proceselor de cutare
este descris de:
- efortul suplimentar de prelucrare dat de funcia hash care poate

avea n unele situaii un nivel de complexitate ridicat;


apariia n cadrul tabelei a coliziunilor acestea sunt generate de
situaia n care dou valori Xh i YH ce aparin domeniului de
definiie a funcie hash conduc la obinerea de valori identice,
hash(Xh) = hash(Yh); evitarea coliziunilor implic realizarea de
operaii suplimentare prin care s se identifice poziia elementului
n cadrul mulimii; printre cele mai utilizate tehnici de evitare a
coliziunilor se numr chaining, re-hashing, linear probing,
quadratic probing i overflow area, [Will96], [Seng94].
Din aceste puncte de vedere, tabela de dispersie utilizat n procesul
de regsire a informaiei se descrie ca o structur n care datele sunt
stocate n tabele cu adresare direct, iar poziia acestora este determinat
prin prelucrarea cheii de cutare cu o funcie hash, figura 17.1.
-

Cheie de cutare
Funcie hash
Valoarealfanumeric

Valoarenumeric
Valoare[Elem1, Elemn]

EVITARE COLIZIUNI

Elem1

Elemn/2-1 Elemn/2 Elemn/2+1

Elemn

Tabel cu acces direct

Figura 17.1 Tabela de dispersie

2. Chei si funcii hash


Pentru a identifica n mod unic fiecare nregistrare sunt utilizate valori
dintr-un domeniu bine definit. Asocierea dintre aceste valori unice i
nregistrrile pe care le reprezint este de unu la unu. n funcie de tipul
valorii cu rol de cheie se identific:
- chei
numerice
reprezentate
prin
intermediul
tipurilor
fundamentale definite de limbajul de programare utilizat;
- chei alfanumerice reprezentate prin iruri de caractere;
- chei compuse definite pe baza a mai multor atribute;
Rolul funciei hash este de a prelucra cheia asociat fiecrei
nregistrri i de a determina poziia n cadrul tabelei de dispersie a
elementului respectiv. Deoarece nu exist o funcie hash general, iar
alegerea acesteia se face n funcie de caracteristicile mulimii de valori
chei, sunt utilizate modele matematice bazate pe:
- mprire n modul; aceast metod are un grad ridicat de
utilizare n diferitele modele de implementare a tabelelor de
dispersie prin prisma complexitii sczute a modelului i a
uurinei n implementare; indiferent de forma cheii de cutarea,
aceasta este transformat ntr-o valoare numeric i apoi

transpus n mulimea [0nht-1], unde nht reprezint


dimensiunea tabelei de dispersie; acest tip de funcie are asociat
modelul:
pozitie_tabela = val_cheie % val_baza

(17.7)

unde:

pozitie_tabela valoarea hash obinut;


val_cheie valoarea numeric ce identific unic fiecare

nregistrare;
val_baza valoarea numeric stabilit la definirea modelului; Valoarea
utilizat ca baz n modelul funciei hash este dat de dimensiunea
tabelei de dispersie; obiectivul definirii funciei hash este de a obine un
model care s minimizeze mulimea de chei diferite ce conduc la aceeai
valoare pozitie_tabela; n acest sens se utilizeaz numere prime
apropiate de numrul total de nregistrri; astfel, dac cheile
nregistrrilor definesc o mulime continu de valori unice, valorile hash
determinate vor acoperi toat mulimea [0..val_baza-1]; pentru a stabili
dimensiunea iniial a tabelei de dispersii sunt alese numere prime
particulare; de exemplu limbajul Java definete o clas HashTable ce
descrie o tabel de dispersie cu dimensiunea iniial egal cu 101;
valoarea nu este aleas la ntmplare deoarece permite redimensionarea
tabelei la o nou valoare prim; pentru cazuri generale, este indicat s
se foloseasc un numr prim determinat prin relaia:
dimensiune_hash = (4*i+3) cu i=0, 1, 2, 3,

(17.8)

nmulirea cu un numr real aleatoriu i prelucrarea ulterioar a


prii zecimale valoarea cheii de cutare este nmulit cu un
numr din intervalul [0;1) ce este ales aleatoriu; n urma
nmulirii se obine o valoarea temporara, temp, a crei parte
zecimal are valori cuprinse n intervalul [0 ;1); nmulind temp
cu dimensiunea tabelei de dispersie, dimensiune_hash, se obine
o valoare n intervalul [0, dimensiune_hash-1] ce reprezint
poziia elementului cutat n tabel; relaia 17.9 descrie procesul
de determinare a valorii hash:

val_hash=((val_cheie*random[0;1))[(val_cheie*random[0;1))])*nth

(17.9)

unde:
val_hash valoarea hash calculat;
val_cheie valoarea cheii de cutare;
random[0;1) numr aleatoriu din mulimea [0;1);
nth
dimensiunea tabelei de dispersie.
-

utilizarea unui bloc de bii obinut prin prelucrarea cheii de


cutare de exemplu se definete funcia care multiplic
valoarea codului i care determin valoarea hash pe baza celor 10
bii din interiorul acesteia; dac se consider cheile reprezentate
pe 32 de bii atunci relaia este:

val_hash = ((val_chei * val_cheie)>>11) % nhash

unde:

(17.10)

prelucrarea codurilor ASCII ale caracterelor alfanumerice n


cazul n care cheia de cutare este dat de o secven de
caractere atunci este necesar ca aceasta s fie prelucrat pentru
a se genera un numr ntreg care s indice poziia elementului n
tabel; prelucrarea se face pe baza codului ASCII asociat
caracterului; pe baza primului caracter din cheie se definete
relaia:
val_hashs1 = string_cheie[0] % 255

(17.11)

val_hashs1 valoarea hash calculat;


string_cheie valoarea cheii de cutare;
Relaia anterioar definete un model cu un nivel de complexitate
sczut ce este destinat gestiunii unei colectiviti mici de
elemente; n cazul n care valoarea cheii reprezint numele unei
persoane, modelul este ineficient deoarece genereaz multe
coliziuni pentru nume diferite dar care ncep cu acelai caracter;
rafinarea acestui model se poate face prin preluarea mai multor
caractere din irul respectiv; de exemplu se definete o nou
relaie:
val_hashs2=(string_cheie[0]+string_cheie[lungimestring_cheie] )%dim_has (17.12)

unde:
val_hashs2
valoarea hash calculat;
string_cheie valoarea cheii de cutare;
lungimestring_cheie dimensiunea irului de caractere;
dim_hash
dimensiunea tabelei de dispersie;
ce ia n calcul primul i ultimul caracter; de asemenea, pentru a
nu reduce dimensiunea tabelei la maxim 255 elemente, se
utilizeaz un numr prim, dim_hash suficient de mare; alte funcii
hash de prelucrare a cheilor alfanumerice analizeaz toate
caracterele din ir; de exemplu relaia
lungime _ cheie

val_hashs3 =

ASCII (string _ cheie[i]) % dim_hash (17.13)


i1

unde:
val_hashs3
valoarea hash calculat;
string_cheie valoarea cheii de cutare;
lungime_cheie dimensiunea irului de caractere;
dim_hash dimensiunea tabelei de dispersie;
determin valoarea hash pe baza sumei codurilor ASCII asociate
tuturor caracterelor din cheie;

nmulirea cu un numr real definit; aceast valoare este


determinat prin evaluarea expresiei

5 1 sau a expresiei
2

m 1

5 1

; funcia hash definit pe baza acestui model este

2
f(val_cheie) = [val_cheie * m]

(17.14)

acest model este implementat n cadrul funciile de rehashing ce


sunt utilizate n cadrul procedurilor de rezolvare a coliziunilor.
Dificultatea n definirea funciilor hash const n identificare acelui
model care s minimizeze numrul coliziunilor i care s genereze o
distribuie uniform a valorilor pe ntreg intervalul.

3. Evitarea coliziunilor
Funciile de evitare a coliziunilor definesc metode de regsire a
elementelor ce sunt descrise de chei cu valori diferite dar care conduc la
valori hash identice ceea ce implic poziii identice n cadrul structurii:
- chaining implementreaz lucrul cu liste fiecare poziiei din
cadrul tabelei de dispersie conine captul unei liste de elemente
cu valori hash egale; regsirea unui element presupune
determinarea poziiei n cadrul tabelei prin calcularea valorii hash
i parcurgerea secvenial a listei ataate poziiei respective dup
valoarea cheii de cutare, figura 17.2;

Tabel de dispersie

valoare cheie
hash(x) = k

legtura nod list

hash(y) = k
hash(z) = k

NULL

k+1

Figura 17.2 Metoda chaining de evitare a coliziunilor n tabele de dispersie.


-

re-hashing presupune aplicarea n cascad a aceleiai funcii hash


sau a altui model dintr-o mulime de funcii pn cnd valoarea
obinut reprezint o poziie liber din cadrul tabelei de dispersie;
la fiecare pas al procesului de regsire, valoarea cheii de cutare
este introdus ntr-o list de funcii hash pn cnd se identific
elementul cu valoarea cutat sau nu mai exist alte posibiliti
de a recalcula valoarea hash; tipul i numrul de funcii hash
aplicate valorilor intermediare descriu o procedur bine definit de
cutare, respectiv iniializare element nou, pentru a conduce de
fiecare dat la aceleai rezultate, figura 17.3;
Tabel de dispersie

hash1(x) = k

hash1(y) = k
k+n

hash1(z) = k+n

hash2(y) = k+n
hash3(y) = k+m

k+m

Figura 17.3 Metoda rehashing de evitare a coliziunilor


n tabele de dispersie
-

linear probing se bazeaz pe cutarea secvenial a primei poziii


libere n care s fie inserat elementul nou, poziie aflat la stnga
sau la dreapta coliziunii; n cazul cutrii, procesul presupune
verificarea elementelor adiacente poziiei indicate de valoarea
hash; cu toate c are un grad sczut de complexitate, aceast
metod de evitare a coliziunilor are ca efecte secundare gruparea
coliziunilor de acelai tip n aceeai zon, cluster, fapt care
conduce la creterea probabilitii de apariie a coliziunilor pentru
valorile hash adiacente, figura 17.4;

Tabel de dispersie

hash(y) = k

hash(x) = k

verificare poziii

k+1

hash(z) = k+1

adiacente

k+2

Figura 17.4 Metoda linear probing de evitare a coliziunilor n


tabele de dispersie
-

quadratic probing este o metod de tipul linear probing care evit


crearea grupurilor de coliziuni prin utilizarea unui pas de regsire
a urmtoarei poziii libere diferit de 1; astfel, n caz de coliziuni
au loc salturi n tabela de dispersie din dou n dou poziii sau
din patru n patru; n general, pentru a determina urmtoare
poziie n care s se insereze un element nou sau n care s se
caute un element existent este dat de funcia:
poziie = hash(X)+c*i2

(17.15)

unde:
poziie noua poziie din tabela de dispersie n care se insereaz sau se
caut un element;
X valoarea cheii asociate elementului;
hash(X) poziia indicat de valoarea hash a elementului care se adaug
sau se cut;
c
valoare constant definit n mulimea {1, 2, 4};
i numrul operaiei de rehash sau numrul de poziii verificate. Prin
utilizarea de repoziionri pe poziii neadiacente se evit gruparea
coliziunilor n aceeai zon din tabela de dispersie, figura 17.5;

Tabel de dispersie

hash(y) = k

hash(y)+2*12

hash(x) = k

k+2

hash(y)+2*22

hash(z) = k+2

k+8

Figura 17.5 Metoda quadratic probing de evitare a coliziunilor n


tabele de dispersie

overflow area presupune o abordare ce mparte tabela de


dispersie n dou zone, primar pentru reinerea elementelor
iniiale i secundar alocat elementelor ce genereaz coliziuni; la
apariia unei coliziuni, fie la operaia de regsire sau la adugarea
unui element nou, se utilizeaz un element al zonei secundare
pentru a reine noua valoare sau pentru a continua cutarea;
accesul la zona secundar se realizeaz doar prin intermediul unui
pointer din zona primar, funcia hash negenernd poziii n acest
interval de valori; aceast metod, descris n figura 17.6,
permite o regsire mai rapid a informaiilor dect metoda
chaining care presupune parcurgerea de liste;
Tabel de dispersie

hash(x) = k

zon principal

hash(y) = k

zon overflow
y

Figura 17.6 Metoda overflow de evitare a coliziunilor n tabele de dispersie


Se observ n cazul tabelelor de dispersie c probabilitatea de apariie
a coliziunilor la inserare sau la cutare crete proporional cu gradul de
utilizare a tabelei. n cele mai multe cazuri, funciile hash cu un grad redus
de complexitate nu conduc la rezultate unice pentru valori de intrare
distincte. Din acest motiv, cu ct tabela pune la dispoziie un numr din ce
n ce mai mic de poziii disponibile, crete riscul de a avea numeroase
elemente cu chei de cutare diferite care ar trebui s se regseasc pe
poziii identice. Metodele de evitare a coliziunilor rezolv parial problema
deoarece ele plaseaz elementele noi pe alte poziii definind o nou cauz
pentru coliziuni viitoare.
Pentru a rezolva aceast situaie i pentru a menine eficiena
operaiei de cutare la un nivel acceptabil, astfel nct s nu se parcurg
toat mulimea de elemente la fiecare operaie de regsire de informaie, se
analizeaz gradul de utilizare a tabelei hash, GUhash.

GU
hash

NPO *100
NTP

unde:
NPO numrul de poziii ocupate;
NTP numrul total de poziii.

(17.16)

care este meninut la o valoarea mai mic de 50%. n ciuda faptului c are
loc o gestiune ineficient a spaiului, eficiena abordrii se bazeaz pe o
vitez de regsire mare. Pentru a menine valoarea indicatorului GUhash sub
limit impus, tabela se redimensioneaz prin dublarea numrului de poziii.
n cazul n care modelul funciei hash este bazat pe mprirea n modul la
dimensiunea acesteia, redimensionarea trebuie s conduc la o nou
dimensiune care s reprezinte tot un numr prim. Avnd n vedere
importana acestor tipuri de numere, lucru evideniat la descrierea tipurilor
de funcii hash, redimensionarea se face prin intermediul relaiei
dimensiune_noua = dimensiune_curenta*2 + 1

(17.17)

n cazul limbajului Java, unde dimensiunea iniial a tabelei de


dispersie este 101, redimensionarea ulterioar a acesteia utiliznd relaia
descris conduce la o serie de valori care reprezint tot valori prime. De
exemplu 203 i 407. n cazul n care relaia utilizat pentru a determina
numrul prim este
dimensiune_hash = (4*i+3) cu i=0, 1, 2, 3,

(17.18)

redimensionarea se realizeaz prin nlocuirea lui i cu 2*i. Astfel, noua


dimensiune va fi reprezentat tot de un numr prim.

S-ar putea să vă placă și