În urma parcurgerii articolului, studentul va fi capabil să:
Trie-ul, cunoscut și sub numele de arbore de prefixe(prefix tree) este un arbore de căutare care permite operații de inserare si cautare de elemente in complexitate O(L) (L - lungimea cheii).
De obicei trie-ul este folosit pentru a stoca string-uri si valori asociate acestora. Pe parcursul semestrului am studiat alte 2 structuri de date care pot efectua aceleasi operatii: hashtable-ul si arborele binar de cautare. De ce am studia inca o structura de date care poate realiza aceleasi operatii?
Un trie este o structura de tip arbore care reține asocieri de tip cheie - valoare. Fiecare nod reprezintă fie o cheie, fie prefixul uneia. Radacina utilizeaza pe post de cheie un string vid(””). Copiii rădăcinii reprezintă noduri asociate cheilor sau prefixelor de chei de dimensiune 1, iar copiii acestora reprezintă chei sau prefixe de chei de dimensiune 2 s.a.m.d. In concluzie putem spune ca pentru un nod aflat la distanta k de radacina, acesta are o cheie de lungime k.
Puteti observa in desenul de mai jos cum arata un trie. De observat ca nodurile ce contin valori sunt colorate cu mov(nodurile corespunzatoare cheilor “in” si “int” contin si ele valori, chiar daca nu sunt noduri frunza)
Fiind un arbore, trie-ul va respecta formatul standard a acestei structuri de date. Fiecare nod contine copiii, retinuti de obicei intr-un vector si valoare.
#ifndef __TRIE_H #define __TRIE_H #include <cstdio> #include <cstdlib> #include <vector> template <typename T> class Trie { public: Trie() {} Trie(int capacity, T value) : words_count(0), children(capacity, NULL), value(value) { } ~Trie() {} T get(string key) { //assert(key.length() > 0); //assert('a' <= key[0] && key[0] <= 'z'); char c = key[0]; if (children[c - 'a'] == NULL) return NULL; if (key.length() == 1) return children[c - 'a']->value; return children[c - 'a']->get(key.substr(1)); } void insert(string key, T value){} T remove(string key){} // returns the value of the node to be removed int get_num_nodes_with_prefix(string key) {} private: int count; vector<Trie *> children; T value; }; #endif // __TRIE_H
In functie de problema pe care dorim sa o rezolvam, capacitatea poate varia. In exemplul de mai jos vom alege cheile sa fie formate doar din litere mici ale alfabetului: