Junior
Kaip veikia maišos lentelė?
sobes.tech AI
Atsakymas iš AI
Žodynėlis (hash table) — tai duomenų struktūra, įgyvendinanti asociatyvųjį masyvą.
Veikimo principas:
- Hash'inimas. Kiekvienam raktui (key) apskaičiuojamas hash kodas (hash code) naudojant hash funkciją (hash function). Hash kodas yra sveikas skaičius.
- Indeksavimas. Hash kodas naudojamas nustatyti indeksą (index) vidinėje struktūros masyve (arba vektoriuje). Paprastai indeksas skaičiuojamas kaip
hash_code % array_size, kurarray_sizeyra masyvo dydis. - Saugojimas. Suradus indeksą, masyve saugoma susijusi su raktu reikšmė (value).
Problemos ir jų sprendimai:
- Kolizijos. Skirtingi raktai gali duoti tą patį hash kodą ir, atitinkamai, tą patį indeksą masyve. Tai vadinama kolizija.
- Kolizijų sprendimo metodai:
- Atskirų grandinių (Separate Chaining) metodas: Kiekvienoje masyvo ląstelėje saugomas sąrašas (arba vektorius) porų "raktas-reikšmė". Kolizijos atveju nauja pora pridedama į šį sąrašą. Paieška pagal indeksą apžvelgiama atitinkamas sąrašas, kad rastų reikiamą raktą.
- Atvirosios adresacijos (Open Addressing) metodas: Kolizijos atveju ieškoma kita laisva ląstelė masyve pagal tam tikrą taisyklę (bandymą).
- Linijinis bandymas (Linear Probing): Tikrinamos ląstelės
index + 1,index + 2ir t.t., imant modulį pagal masyvo dydį. - Kvadratinis bandymas (Quadratic Probing): Tikrinamos ląstelės
index + 1^2,index + 2^2ir t.t., imant modulį pagal masyvo dydį. - Dvigubas hash'inimas (Double Hashing): Naudojama antra hash funkcija, nustatant žingsnio dydį.
- Linijinis bandymas (Linear Probing): Tikrinamos ląstelės
- Kolizijų sprendimo metodai:
Privalumai:
- Vidutiniškai, įterpimo, ištrynimo ir paieškos operacijos vykdomos su sudėtingumu O(1).
Trūkumai:
- Blogiausiu atveju (pavyzdžiui, esant daug kolizijų arba blogai hash funkcijai) operacijų sudėtingumas gali siekti O(n), kur n — elementų skaičius.
- Reikalauja papildomos atminties (pavyzdžiui, sąrašų naudojant atskirų grandinių metodą arba bandymui naudojant atvirą adresaciją).
Pavyzdys naudojimo C++ (std::unordered_map):
#include <unordered_map>
#include <string>
#include <iostream>
int main() {
// Sukurti hash lentelę (unordered_map)
std::unordered_map<std::string, int> amžius;
// Įterpti elementus
amžius["Alice"] = 30;
amžius["Bob"] = 25;
amžius["Charlie"] = 35;
// Gauti reikšmę pagal raktą
std::cout << "Alice amžius: " << amžius["Alice"] << std::endl;
// Rasti elementą
if (amžius.count("Bob")) {
std::cout << "Bob yra žemėlapyje." << std::endl;
}
// Ištrinti elementą
amžius.erase("Charlie");
return 0;
}