Notatii: tipElement - tipul elementelor tabelei tipCheie - tipul cheii t - tabela e - valoare a lui tipElement k - valoare a lui tipCheie b - valoare booleana contor - valoare intreaga Operatori: CreazaTabelaVida(t) - procedura care face pe t vid TabelaVida(t) -> b - functie booleana care returneaza "true" daca tabela e goala TabelaPlina(t) -> b - functie booleana care returneaza "true" daca tabela e plina CheieElemTabela(e) -> k - functie ce returneaza cheia elementului e CheieGasita(t,k) -> b - functie ce returneaza "true" daca cheia k se gaseste in t InserElemTabela(t,e) - procedura care insereaza pe e in t, presupunind ca acesta nu exista SuprimaElemTabela(t,k) - procedura ce suprima din tabela t elementul cu cheia k, presupunind ca acest element exista FurnizeazaElemTabela(t,k) -> e - functie care returneaza elementul cu cheia k, presupunind ca elementul exista TraverseazaTabela(t,Vizitare(ListaArgumente) - procedura ce executa procedura Vizitare pentru fiecare element al tabelei t DimensTabela(t) -> contor - functie ce returneaza numarul de elemente din tabela; se poate actualiza o variabila contor la fiecare insertie si suprimare Actualizare(t,e) - procedura ce actualizeaza intrarea din tabela ce contine elementul e; se poate scrie prin apelul operatorilor anterior definiti : SuprimaElemTabela(t,CheieElemTabela(e)) si InserElemTabela(t,e)
Ca un dezavantaj apare si faptul ca pentru rezervarea spatiului de memorie statica al tabloului, trebuie evaluat numarul de insertii ce se vor face.
Implementarea este avantajoasa cind se realizeaza traversari frecvente in ordinea cheilor si cind nu se cunoaste numarul maxim de elemente.
Se defineste o functie de asociere H, care e de fapt o functie de
dispersie:
H : tipCheie -> 0_p-1,
ce asociaza fiecarei chei cite un indice de tablou.
Prin metoda dispersiei, care se mai numeste si "transformarea cheilor" sau "hashing" ( amestecare ), pentru inregistrarea unui element cu cheia k, se determina indicele l=H(k), apoi se depune elementul la intarea l. Pentru o alta cheie k_prim, avind acelasi indice asociat l=H(k)=H(k_prim), se ajunge la "situatia de coliziune", care se poate rezolva prin mai multe metode.
Pentru cautarea unei chei k, se verifica daca elementul de la intrarea H(k) are cheia cautata, in caz negativ, s-a ajuns la coliziune.
Pentru aplicarea tehnicii dispersiei, care duce la performante foarte bune,
trebuie solutionate doua probleme:
- definirea functiei de dispersie H
- rezolvarea situatiilor de coliziune.
Foarte des se foloseste functia: H(k)=ord(k) mod p, unde ord(k) precizeaza numarul de ordine al cheii k in multimea tuturor cheilor.
In cazul cheilor siruri de caractere se pot folosi functiile:
H(k)=( suma(i=1,length(k)) 2^i * ord(k[i]) ) mod p, sau
H(k)=( suma(i=1,length(k)) ord(k[i]) ) mod p.
Se demonstreaza ca pentru repartitia cit mai uniforma a cheilor, dimensiu- nea p a tabloului trebuie sa fie numar prim. Daca p e o putere a lui 2, calculul indicelui l s-ar face mai rapid, dar posibilitatea de aparitie a coliziunilor ar fi mult mai mare.
l:=H(k); nr_incercari:=0; repeat if t[l].cheie=k then {element gasit} else if t[l].cheie=liber then {elementul nu e in tablou, se introduce} else begin {tratarea coliziunii} inc(nr_incercari); l:=H(k)+g(nr_incercari) end until *gasit or *s-a introdus or *tabela e plina;O varianta pentru functia g(nr_incercari) este cea care duce la testarea indicilor consecutivi din tablou, acesta fiind exploatat circular, deci indicele testat la pasul nr_incercari este:
Dezavantajul acestei adresari liniare este ca are tendinta de a ingramadi nodurile in continuarea celor existente, coliziunile aparind mai des.
Adresarea patratica cu indicele la pasul nr_incercari:
l=(H(k)+nr_incercari^2) mod p,
elimina dezavantajul anterior, dar conduce la probabilitatea ( mica ) de a nu
se putea gasi nici o intrare libere, desi tabele nu e plina.
Formula ilustreaza performantele foarte bune ale metodei dispersiei, de exemplu 2.56 incercari la un factor de umplere de 0.9.
Daca rezolvarea coliziunilor se face prin adresare directa, formula devine:
E=(1-f/2)/(1-f),
pastrind inca performante bune, de exemplu 5.5 incercari la un factor de
umplere de 0.9.
In ciuda performantelor bune, metoda dispersiei are dezavantajele:
- dimensiunea tabloului trebuie estimata anterior, lucru ce nu e posibil
intotdeauna ( caz in care se folosesc liste sau arbori ), ajungindu-se fie la
risipa, fie la depasirea memoriei alocate; in plus, pentru performante bune,
alocarea initiala trebuie facuta cu 10% mai mult decit e necesar;
- suprimarea cheilor este dificila, mai putin in cazul inlantuirii directe.