一、Trie 树是我一直想看却一直拖着没看的数据结构。主要应用的思想是通过构建树结构,使得前缀相同的字符串可共享前缀序列,一旦构建好树结构后,便可实现快速检索。
适用场景:1)找到所有前缀相同的字符串 2)以字典序枚举数据集中的每个字符串。
哈希表在上述两种场景下会有大量的哈希碰撞(hash collisions)且搜索的时间复杂度很高(最差情形下为 O(n),n为插入的键值数)。故相较于哈希表,Trie可通过存储相同前缀的字符串节省更多的空间,故搜索的时间复杂度仅为O(m), m为键长(即字符串长度)
二、主要的应用有:构建字典(查询某个单词是否在字典中)、自动纠正语法错误、自动补齐单词、IP地址路由选择等。
1)根节点的特点:
1. Trie为有根树,根节点为空,不表示任何字符
2. 每个节点最多有R个孩子(若字符串中每个字符取值为‘a’~‘z’,则R=26),第i个孩子表示字母表中的第i个字符
2)插入元素
依次遍历字符串中的每个元素,若该元素存在,继续遍历下一元素;否则,插入一新的节点。
3)查找某字符串是否存在
与2)类似,依次遍历字符串中的每个元素,若该元素存在,继续遍历下一元素;否则,返回false。
例题:LeetCode 208. Implement Trie
代码如下:
class TrieNode{ public: char var; //该节点对应的字符 bool isword; //标记从根节点到该节点是否表示一个单词或另一单词的前缀 TrieNode* child[26]; //子节点用一个数组表示,实现简单但耗内存 // Initialize the data structure TrieNode() { var = 0; isword = false; memset(child, 0, sizeof(child)); } TrieNode(char c) { var = c; isword = false; memset(child, 0, sizeof(child)); } }; class Trie { public: /** Initialize your data structure here. */ Trie() { root = new TrieNode(); } /** Inserts a word into the trie. */ void insert(string word) { if(word.length()<=0) return; TrieNode *pNode = root; for(int i=0; i<word.length(); ++i) { char c = word[i]; if(pNode->child[c-'a'] == 0) { TrieNode *pNew = new TrieNode(c); pNode->child[c-'a'] = pNew; } pNode = pNode->child[c-'a']; } pNode->isword = true; } /** Returns if the word is in the trie. */ bool search(string word) { TrieNode *pNode = root; if(word.length()<=0) return true; for(int i=0; i<word.length(); ++i) { char c = word[i]; pNode = pNode->child[c-'a']; if(pNode==NULL) return false; } return pNode->isword; } /** Returns if there is any word in the trie that starts with the given prefix. */ bool startsWith(string prefix) { if(prefix.length()<=0) return true; TrieNode *pNode = root; for(int i=0; i<prefix.length(); ++i) { char c = prefix[i]; pNode = pNode->child[c-'a']; if(pNode==NULL) return false; } return true; } 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); */
参考链接: https://leetcode.com/problems/implement-trie-prefix-tree/solution/
https://blog.csdn.net/sunao2002002/article/details/46661761