Trie树主要用于字符串前缀匹配,树的根节点不存元素,其余节点存一个字符。对于一个字符串,其实就是顺着一条路径搜索的过程。
TrieNode节点有一个bool表示是否是一个word的结束,还有一个TrieNode *的数组,指向所有的孩子。
插入和搜索的时间复杂度都是 O(n),n表示给定字符串的长度。
使用 Trie Tree,也可以非常简单找到所有前缀匹配上的字符串。
class TrieNode{ public: bool isend; // if the end of word, isend=true vector<TrieNode *> next; TrieNode():isend(false), next(26,NULL){} }; class Trie { public: /** Initialize your data structure here. */ Trie() { root = new TrieNode(); } /** Inserts a word into the trie. */ void insert(string word) { if (search(word)) return; TrieNode *p=root; for (char ch:word){ if (p->next[ch-'a']==NULL) p->next[ch-'a'] = new TrieNode(); p = p->next[ch-'a']; } p->isend = true; } /** Returns if the word is in the trie. */ bool search(string word) { TrieNode *p=root; for (char ch:word){ p = p->next[ch-'a']; if (p==NULL) return false; } return p->isend==true; } /** Returns if there is any word in the trie that starts with the given prefix. */ bool startsWith(string prefix) { TrieNode *p=root; for (char ch:prefix){ p = p->next[ch-'a']; if (p==NULL) return false; } dfs(p,prefix); return true; } void dfs(TrieNode *root, string s){ if (root->isend) cout<<s<<endl; for (char ch='a';ch<='z';++ch){ if (root->next[ch-'a']) dfs(root->next[ch-'a'],s+ch); } } private: TrieNode *root; }; /** * Your Trie object will be instantiated and called as such: * Trie obj = new Trie(); * obj.insert(word); * bool param_2 = obj.search(word); * bool param_3 = obj.startsWith(prefix); */
References: