hash table c programs implement hash table
Aquest tutorial explica les taules i els mapes de hash de C ++. També coneixereu les aplicacions i la implementació de la taula Hash a C ++:
El hash és una tècnica amb la qual podem assignar una gran quantitat de dades a una taula més petita mitjançant una 'funció hash'.
Mitjançant la tècnica de hash, podem cercar les dades amb més rapidesa i eficiència en comparació amb altres tècniques de cerca, com ara la cerca lineal i binària.
Entenem la tècnica de hash amb un exemple en aquest tutorial.
=> Llegiu la sèrie de formació Easy C ++.
Què aprendreu:
Hashing a C ++
Prenguem un exemple de biblioteca universitària que alberga milers de llibres. Els llibres estan ordenats per temes, departaments, etc. Però, cada secció conté nombrosos llibres que dificulten molt la cerca de llibres.
Per tant, per superar aquesta dificultat assignem un número o una clau únics a cada llibre perquè puguem conèixer instantàniament la ubicació del llibre. Això, de fet, s’aconsegueix mitjançant el hash.
Seguint amb el nostre exemple de biblioteca, en lloc d’identificar cada llibre en funció del seu departament, tema, secció, etc. que pugui donar lloc a una cadena molt llarga, calculem un valor enter o una clau per a cada llibre de la biblioteca mitjançant una funció única i emmagatzemeu aquestes claus en una taula independent.
La funció única esmentada anteriorment s'anomena 'funció Hash' i la taula independent es diu 'Taula Hash'. S'utilitza una funció de hash per assignar el valor donat a una clau única particular de la taula de hash. Això es tradueix en un accés més ràpid als elements. Com més eficient sigui la funció de resum, més eficaç serà el mapatge de cada element a la clau única.
Considerem una funció de hash h (x) que assigna el valor ' x 'A' x% 10 ”A la matriu. Per a les dades donades, podem construir una taula de hash que contingui claus o codis Hash o Hash tal com es mostra al diagrama següent.
Al diagrama anterior, podem veure que les entrades de la matriu s’assignen a les seves posicions a la taula de hash mitjançant una funció de hash.
Per tant, podem dir que l'hash s'implementa mitjançant dos passos, tal com s'esmenta a continuació:
# 1) El valor es converteix en una clau sencera única o hash mitjançant una funció hash. S'utilitza com a índex per emmagatzemar l'element original, que cau a la taula de hash.
millor escaneig i reparació gratuïta de l’ordinador
Al diagrama anterior, el valor 1 de la taula de hash és l'única clau per emmagatzemar l'element 1 de la matriu de dades que es dóna al LHS del diagrama.
# 2) L'element de la matriu de dades s'emmagatzema a la taula de hash on es pot recuperar ràpidament mitjançant la clau hash. Al diagrama anterior, hem vist que hem emmagatzemat tots els elements a la taula de hash després de calcular les seves respectives ubicacions mitjançant una funció de hash. Podem utilitzar les expressions següents per recuperar índexs i valors de resum.
hash = hash_func(key) index = hash % array_size
Funció Hash
Ja hem esmentat que l'eficiència del mapatge depèn de l'eficiència de la funció de hash que fem servir.
Una funció de resum ha de complir bàsicament els requisits següents:
- Fàcil de computar: Una funció de hash hauria de ser fàcil de calcular les claus úniques.
- Menys col·lisions: Quan els elements equivalen als mateixos valors clau, es produeix una col·lisió. Hi hauria d’haver col·lisions mínimes en la mesura del possible a la funció de hash que s’utilitzi. Com que probablement es produiran col·lisions, hem d’utilitzar tècniques adequades de resolució de col·lisions per tenir cura de les col·lisions.
- Distribució uniforme: La funció hash hauria de tenir com a resultat una distribució uniforme de les dades a la taula de hash i, per tant, evitar la concentració.
Taula de hash C ++
La taula hash o un mapa hash és una estructura de dades que emmagatzema els indicadors cap als elements de la matriu de dades original.
A l'exemple de la nostra biblioteca, la taula de hash de la biblioteca contindrà indicadors per a cadascun dels llibres de la biblioteca.
Tenir entrades a la taula de hash facilita la cerca d’un element concret a la matriu.
Com ja s'ha vist, la taula hash utilitza una funció hash per calcular l'índex a la matriu de compartiments o ranures amb els quals es pot trobar el valor desitjat.
Penseu en un altre exemple amb la matriu de dades següent:
Suposem que tenim una taula de hash de la mida 10, tal com es mostra a continuació:
Ara fem servir la funció de resum que es mostra a continuació.
Hash_code = Key_value % size_of_hash_table
Això equival a Hash_code = Key_value% 10
Mitjançant la funció anterior, assignem els valors clau a les ubicacions de la taula de hash tal i com es mostra a continuació.
Element de dades | Funció hash | Hash_code |
---|---|---|
22 | 22% 10 = 2 | 2 |
25 | 25% 10 = 5 | 5 |
27 | 27% 10 = 7 | 7 |
46 | 46% 10 = 6 | 6 |
70 | 70% 10 = 0 | 0 |
89 | El 89% 10 = 9 | 9 |
31 | El 31% 10 = 1 | 1 |
Utilitzant la taula anterior, podem representar la taula de hash de la següent manera.
Per tant, quan necessitem accedir a un element des de la taula de hash, trigarem O (1) a fer la cerca.
Col·lisió
Normalment calculem el codi hash mitjançant la funció hash de manera que puguem assignar el valor de la clau al codi hash de la taula de hash. A l'exemple anterior de la matriu de dades, inserim un valor 12. En aquest cas, el codi hash_ per al valor clau 12 serà 2. (12% 10 = 2).
Però a la taula de hash, ja tenim un mapatge al valor-clau 22 de hash_code 2, tal com es mostra a continuació:
Com es mostra més amunt, tenim el mateix codi hash per a dos valors, 12 i 22, és a dir, 2. Quan un o més valors clau equivalen a la mateixa ubicació, resulta una col·lisió. Per tant, la ubicació del codi hash ja està ocupada per un valor clau i hi ha un altre valor clau que cal col·locar a la mateixa ubicació.
En el cas del hash, fins i tot si tenim una taula de hash de mida molt gran, és probable que hi hagi una col·lisió. Això es deu al fet que trobem un valor únic petit per a una clau gran en general, per tant és completament possible que un o més valors tinguin el mateix codi de hash en cada moment.
Tenint en compte que la col·lisió és inevitable en el hash, sempre hem de buscar maneres de prevenir o resoldre la col·lisió. Hi ha diverses tècniques de resolució de col·lisions que podem emprar per resoldre la col·lisió que es produeix durant el hash.
Tècniques de resolució de col·lisions
A continuació es detallen les tècniques que podem utilitzar per resoldre les col·lisions a la taula de hash.
Encadenament separat (Open Hashing)
Aquesta és la tècnica de resolució de col·lisions més habitual. Això també es coneix com a hash obert i s’implementa mitjançant una llista enllaçada.
java com eliminar un element d'una matriu
En una tècnica de cadenat independent, cada entrada de la taula de hash és una llista enllaçada. Quan la clau coincideix amb el codi hash, s'introdueix en una llista corresponent a aquest codi hash concret. Així, quan dues tecles tenen el mateix codi hash, les dues entrades s'introdueixen a la llista enllaçada.
Per a l'exemple anterior, la cadena separada es representa a continuació.
El diagrama anterior representa l’encadenament. Aquí fem servir la funció mod (%). Veiem que quan dos valors clau equivalen al mateix codi hash, enllaçem aquests elements amb aquest codi hash mitjançant una llista enllaçada.
Si les claus es distribueixen uniformement a la taula de hash, el cost mitjà de buscar la clau en particular depèn del nombre mitjà de claus de la llista enllaçada. Així, l'encadenament separat continua sent efectiu fins i tot quan hi ha un augment del nombre d'entrades que les ranures.
El pitjor dels casos per a un encadenament separat és quan totes les tecles equivalen al mateix codi hash i, per tant, s’insereixen només en una llista enllaçada. Per tant, hem de buscar totes les entrades de la taula de hash i el cost que siguin proporcionals al nombre de tecles de la taula.
Sondeig lineal (adreçament obert / descomposició tancada)
En la tècnica d’adreçament obert o de sondeig lineal, tots els registres d’entrada s’emmagatzemen a la mateixa taula de hash. Quan el valor clau correspon a un codi hash i la posició assenyalada pel codi hash no està ocupada, el valor clau s'insereix en aquesta ubicació.
Si la posició ja està ocupada, usant una seqüència de sondeig, el valor de la clau s'insereix a la posició següent que està desocupada a la taula de hash.
Per al sondeig lineal, la funció hash pot canviar com es mostra a continuació:
hash = hash% hashTableSize
hash = (hash + 1)% hashTableSize
hash = (hash + 2)% hashTableSize
hash = (hash + 3)% hashTableSize
Veiem que en cas de sondeig lineal l’interval entre ranures o sondes successives és constant, és a dir, 1.
Al diagrama anterior ho veiem al 0thubicació introduïm 10 mitjançant la funció hash 'hash = hash% hash_tableSize'.
Ara l'element 70 també equival a la ubicació 0 a la taula de hash. Però aquesta ubicació ja està ocupada. Per tant, utilitzant sondeig lineal trobarem la següent ubicació que és 1. Com que aquesta ubicació no està ocupada, col·loquem la clau 70 en aquesta ubicació tal com es mostra amb una fletxa.
La taula Hash resultant es mostra a continuació.
L'exploració lineal pot patir el problema de la 'agrupació primària', en què hi ha la possibilitat que les cèl·lules contínues s'ocupin i es redueixi la probabilitat d'inserir un element nou.
També si dos elements obtenen el mateix valor a la primera funció de hash, aquests dos elements seguiran la mateixa seqüència de sonda.
Sondeig quadràtic
El sondeig quadràtic és el mateix que el sondeig lineal, essent l’única diferència l’interval utilitzat per al sondeig. Com el seu nom indica, aquesta tècnica utilitza distància no lineal o quadràtica per ocupar ranures quan es produeix una col·lisió en lloc de distància lineal.
En el sondatge quadràtic, l'interval entre les ranures es calcula afegint un valor polinòmic arbitrari a l'índex ja hash. Aquesta tècnica redueix l’agrupació primària en gran mesura, però no millora en agrupar-la secundàriament.
Hashing doble
La tècnica del doble hash és similar a la sonda lineal. L'única diferència entre el doble hash i el sondeig lineal és que en la tècnica de doble hash l'interval utilitzat per al sondeig es calcula mitjançant dues funcions de hash. Com que apliquem la funció hash a la tecla una rere l’altra, elimina l’agrupació primària i la agrupació secundària.
llocs animats gratuïts per veure en línia
Diferència entre l'encadenament (Open Hashing) i el sondatge lineal (Open Addressing)
Encadenament (Open Hashing) | Sondeig lineal (adreçament obert) |
---|---|
Els valors clau es poden emmagatzemar fora de la taula mitjançant una llista enllaçada independent. | Els valors clau només s’han d’emmagatzemar a la taula. |
El nombre d'elements de la taula de hash pot superar la mida de la taula de hash. | El nombre d'elements presents a la taula de hash no superarà el nombre d'índexs a la taula de hash. |
La supressió és eficient en la tècnica d’encadenament. | La supressió pot ser feixuga. Es pot evitar si no és necessari. |
Com que es manté una llista enllaçada independent per a cada ubicació, l'espai ocupat és gran. | Com que totes les entrades s’allotgen a la mateixa taula, l’espai ocupat és menor. |
Implementació de la taula Hash C ++
Podem implementar el hash utilitzant matrius o llistes enllaçades per programar les taules de hash. A C ++ també tenim una característica anomenada 'mapa de hash' que és una estructura similar a una taula de hash, però cada entrada és un parell clau-valor. En C ++ es diu mapa hash o simplement un mapa. El mapa hash a C ++ no sol estar ordenat.
Hi ha una capçalera definida a la Biblioteca de plantilles estàndard (STL) de C ++ que implementa la funcionalitat dels mapes. Hem cobert Mapes STL en detall al nostre tutorial sobre STL.
La següent implementació serveix per utilitzar el hash mitjançant les llistes enllaçades com a estructura de dades de la taula de hash. També utilitzem 'Encadenament' com a tècnica de resolució de col·lisions en aquesta implementació.
#include #include using namespace std; class Hashing { int hash_bucket; // No. of buckets // Pointer to an array containing buckets list *hashtable; public: Hashing(int V); // Constructor // inserts a key into hash table void insert_key(int val); // deletes a key from hash table void delete_key(int key); // hash function to map values to key int hashFunction(int x) { return (x % hash_bucket); } void displayHash(); }; Hashing::Hashing(int b) { this->hash_bucket = b; hashtable = new list (hash_bucket); } //insert to hash table void Hashing::insert_key(int key) { int index = hashFunction(key); hashtable(index).push_back(key); } void Hashing::delete_key(int key) { // get the hash index for key int index = hashFunction(key); // find the key in (inex)th list list :: iterator i; for (i = hashtable(index).begin(); i != hashtable(index).end(); i++) { if (*i == key) break; } // if key is found in hash table, remove it if (i != hashtable(index).end()) hashtable(index).erase(i); } // display the hash table void Hashing::displayHash() { for (int i = 0; i ' << x; cout << endl; } } // main program int main() { // array that contains keys to be mapped int hash_array() = {11,12,21, 14, 15}; int n = sizeof(hash_array)/sizeof(hash_array(0)); Hashing h(7); // Number of buckets = 7 //insert the keys into the hash table for (int i = 0; i < n; i++) h.insert_key(hash_array(i)); // display the Hash table cout<<'Hash table created:'< Sortida:
Taula de hash creada:
0 -> 21 -> 14
1 -> 15
2
3
4 -> 11
5 -> 12
6
Taula de hash després de suprimir la clau 12:
0 -> 21 -> 14
1 -> 15
2
3
4 -> 11
5
6
La sortida mostra una taula de hash que es crea de la mida 7. Utilitzem la cadena per resoldre la col·lisió. Visualitzem la taula de hash després de suprimir una de les tecles.
Aplicacions de Hashing
# 1) Verificació de contrasenyes: La verificació de contrasenyes se sol fer mitjançant funcions de resum criptogràfic. Quan s'introdueix la contrasenya, el sistema calcula el hash de la contrasenya i s'envia al servidor per verificar-lo. Al servidor, s’emmagatzemen els valors hash de les contrasenyes originals.
# 2) Estructures de dades: Diferents estructures de dades com unordered_set i unordered_map a C ++, diccionaris a python o C #, HashSet i hash map a Java utilitzen tots un parell clau-valor en què les claus són valors únics. Els valors poden ser els mateixos per a diferents claus. Per aplicar aquestes estructures de dades s’utilitza el hashing.
# 3) Resum de missatges: Aquesta és una altra aplicació que utilitza un hash criptogràfic. En els resums de missatges, calculem un hash per a les dades que s’envien i reben o fins i tot els fitxers i els comparem amb els valors emmagatzemats per garantir que no es manipulin els fitxers de dades. L'algorisme més comú aquí és 'SHA 256'.
# 4) Funcionament del compilador: Quan el compilador compila un programa, les paraules clau del llenguatge de programació s’emmagatzemen de manera diferent de les altres identificacions. El compilador utilitza una taula de hash per emmagatzemar aquestes paraules clau.
# 5) Indexació de bases de dades: Les taules Hash s’utilitzen per indexar bases de dades i estructures de dades basades en disc.
# 6) Matrius associatius: Les matrius associatives són matrius els índexs dels quals són de tipus de dades diferents de les cadenes semblants a un nombre enter o d'altres tipus d'objectes. Les taules Hash es poden utilitzar per implementar matrius associatives.
Conclusió
El hash és l'estructura de dades més utilitzada, ja que es necessita un temps constant O (1) per a les operacions d'inserció, supressió i cerca. El hash s’implementa principalment mitjançant una funció de hash que calcula un valor de clau més petit únic per a entrades de dades grans. Podem implementar el hash mitjançant matrius i llistes enllaçades.
Sempre que una o més entrades de dades equivalen als mateixos valors de claus, resulta en una col·lisió. Hem vist diverses tècniques de resolució de col·lisions, incloent sondeig lineal, encadenament, etc. També hem vist la implementació de hash en C ++.
Per concloure, podem dir que el hash és, amb diferència, l’estructura de dades més eficient del món de la programació.
=> Cerqueu aquí tota la sèrie de formació C ++.
Lectura recomanada
- Com escriure escenaris complexos de proves de lògica empresarial mitjançant la tècnica de la taula de decisions
- Taula de validació de camp (FVT): una tècnica de disseny de proves per a la validació de camps
- Tutorial QTP # 15 - Ús de punts de control d'àrea de text, taula i pàgina a QTP
- MAPES A STL
- Tot sobre els encaminadors: tipus d’encaminadors, taula d’encaminament i encaminament IP
- Top 40 de les millors preguntes i respostes d’entrevistes de MySQL (preguntes del 2021)
- Top 90 de preguntes i respostes d'entrevistes SQL (DARRERES)
- Comandes de programes d'utilitat Unix: Quin, home, troba Su, Sudo (part D)