Trie data structure (Memory efficient)
}
| #include <iostream> |
| #include <string> |
| #include <map> |
| #include <vector> |
| using namespace std; |
| struct Node { |
| char ch; |
| map<char, Node*> children; |
| }; |
| class Trie { |
| public: |
| Trie() { head.ch = -1; }; |
| ~Trie(); |
| void build_trie(string words[], int length); |
| void insert(string word); |
| void search(string word, bool &result); |
| void print_tree(map<char, Node*> tree); |
| void print(); |
| protected: |
| Node head; |
| // Keep all newly created node in an array, for the ease of |
| // memory release. |
| vector<Node*> children; |
| }; |
| Trie::~Trie() { |
| for (int i=0; i<children.size(); ++i) { |
| delete children[i]; |
| } |
| } |
| void Trie::build_trie(string words[], int length) { |
| for (int i=0; i<length; ++i) { |
| insert(words[i]); |
| } |
| } |
| void Trie::insert(string word) { |
| map<char, Node*> *current_tree = &head.children; |
| map<char, Node*>::iterator it; |
| for (int i=0; i<word.length(); ++i) { |
| char ch = word[i]; |
| if ((it = current_tree->find(ch)) != current_tree->end()) { |
| current_tree = &it->second->children; |
| continue; |
| } |
| if (it == current_tree->end()) { |
| // Display inserting position in the tree, for debug use |
| // |
| // cout << "Inserting " << ch << endl; |
| // cout << "on layer " << endl; |
| // map<char, Node*>::iterator temp = current_tree->begin(); |
| // for (; temp != current_tree->end(); ++temp) |
| // cout << temp->first << endl; |
| Node* new_node = new Node(); |
| new_node->ch = ch; |
| (*current_tree)[ch] = new_node; |
| // For continuous inserting a word. |
| current_tree = &new_node->children; |
| // For the ease of memory clean up. |
| children.push_back(new_node); |
| } |
| } |
| } |
| void Trie::search(string word, bool &result) { |
| map<char, Node*> current_tree = head.children; |
| map<char, Node*>::iterator it; |
| for (int i=0; i<word.length(); ++i) { |
| if ((it = current_tree.find(word[i])) == current_tree.end()) { |
| result = false; |
| return; |
| } |
| current_tree = it->second->children; |
| } |
| result = true; |
| return ; |
| } |
| void Trie::print_tree(map<char, Node*> tree) { |
| if (tree.empty()) { |
| return; |
| } |
| for (map<char, Node*>::iterator it=tree.begin(); it!=tree.end(); ++it) { |
| cout << it->first << endl; |
| print_tree(it->second->children); |
| } |
| } |
| void Trie::print() { |
| map<char, Node*> current_tree = head.children; |
| print_tree(current_tree); |
| } |
| int main(int argc, char** argv) |
| { |
| string words[] = {"foo", "bar", "baz", "barz"}; |
| Trie trie; |
| trie.build_trie(words, 4); |
| cout << "All nodes..." << endl; |
| trie.print(); |
| cout << "Searching..." << endl; |
| bool in_trie = false; |
| trie.search("foo", in_trie); |
| cout << "foo " << in_trie << endl; |
| trie.search("fooz", in_trie); |
| cout << "fooz " << in_trie << endl; |
| trie.search("bar", in_trie); |
| cout << "bar " << in_trie << endl; |
| trie.search("baz", in_trie); |
| cout << "baz " << in_trie << endl; |
| trie.search("barz", in_trie); |
| cout << "barz " << in_trie << endl;; |
| trie.search("bbb", in_trie); |
| cout << "bbb " << in_trie << endl;; |
| return 0; |
No comments:
Post a Comment