12847 afișări Candale Silviu (silviu) 14.11.2017
www.pbinfo.ro
Etichete: nicio etichetă

Să considerăm următoarea problemă:

Se dă o mulțime cu n numere naturale și m întrebări de forma: valoarea X face parte sau nu din mulțime .

Practic avem nevoie de o structură de date care să permită operațiile Caută, Șterge, Inserează cu o complexitate cât mai mică, de preferință O(1)!

Dacă valorile din mulțime sunt relativ mici (să spunem că până la 1000000), o variantă simplă de rezolvare este să folosim un vector caracteristic. Dacă însă valorile date sunt mari, vectorul caracteristic nu mai este o soluție. O modalitatea de rezolvare este folosirea unei tabele de dispersietabelă hash.

Tabela hash este o structură de date prin care valorile cu care lucrăm sunt transformate în valori numerice dintr-un interval numeric stabilit printr-un algoritm unidirecțional, numit funcție de dispersie, și adăugate într-o structură de date care de regulă are dimensiuni mici și care este identificată prin valoarea funcției de dispersie. Astfel, mulțimea valorilor este partiționată astfel încât toate valorile dintr-o submulțime a partiției dau aceiași valoare prin funcția de dispersie.

De exemplu, sa consideram valorile 398 572 944 590 514 981 69 739 499 741 și o funcție de dispersie f(x) = x % 10. În acest caz, mulțimea valorilor se va partiționa în 10 submulțimi, cu următoarele valori:

0 -> {590}
1 -> {981, 741}
2 -> {572}
3 -> {}
4 -> {944, 514}
5 -> {}
6 -> {}
7 -> {}
8 -> {398}
9 -> {69, 739, 499}

Pentru funcția de dispersie f(x) = x % 9 obținem următoarea distribuție a valorilor în tabelă:

0 -> {981}
1 -> {514, 739}
2 -> {398}
3 -> {741}
4 -> {499}
5 -> {572, 590}
6 -> {69}
7 -> {}
8 -> {944}

Constatăm că în ambele situații avem coliziuni (valori din mulțimea dată pentru care valoarea funcției de dispersie este comună). Pentru stocarea valorilor în tabela de dispersia avem nevoie de o structură de date convenabilă. Aceasta poate fi:

  • tablou de liste:
struct nod{
    int info;
    nod * next;
};
const int N = 10;
nod * H[N];
  • vector de vectori STL – această variantă este mai convenabilă, fiind mai ușor de implementat:
int N = 10;
vector<vector<int>> V(n);

Următorul program plasează într-o tabelă hash implementată prin vectori STL valorile din exemplul de mai sus:

#include <iostream>
#include <vector>
#include <sstream>

using namespace std;

int main(){
	string T = "398 572 944 590 514 981 69 739 499 741";
	istringstream sin(T);
	int n = 10;
	vector<vector<int>> H(n);
	int x;
	while(sin >> x)
		H[x % n].push_back(x);

	for(int i = 0 ; i < n ; i ++)
	{
		cout << i << " -> {";
		int cnt = 0;
		for(auto x : H[i])
		{
			if(cnt == 0)
				cout << x;
			else
				cout << ", " << x;
			cnt ++;
		}
		cout << "}\n";		
	}
	return 0;
}

12847 afișări Candale Silviu (silviu) 14.11.2017
www.pbinfo.ro
Du-te sus!