字典树
1.概念
1)Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如小写英文字母的字典树是一个26叉树,数字的字典树是一个10叉树
2)Trie树利用字符串的公共前缀来节约存储空间,字典树存放具有公共前缀的字符串们非常节省空间,相反,对于大量没有公共前缀的字符串,用字典树存就会很消耗内存
3)一个保存了8个key的trie结构,"A", "to", "tea", "ted", "ten", "i", "in", and "inn".如下图所示
2.字典树的三个性质
1)根节点不包含字符,除根节点意外每个节点只包含一个字符
2)从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串
3)每个节点的所有子节点包含的字符串不相同
3.字典树的实现
3.1基本原理
字母树的插入(Insert)、删除( Delete)和查找(Find)都非常简单,用一个一重循环即可,即第i 次循环找到前i 个字母所对应的子树,然后进行相应的操作。实现这棵字母树,我们用最常见的数组保存(静态开辟内存)即可,当然也可以开动态的指针类型(动态开辟内存)。至于节点对儿子的指向,一般有三种方法:
1)对每个结点开一个字母集大小的数组,对应的下标是儿子所表示的字母,内容则是这个儿子对应在大数组上的位置,即标号;
2)对每个结点挂一个链表,按一定顺序记录每个儿子是谁;
3)使用左儿子右兄弟表示法记录这棵树。
3.2代码实现
struct TrieNode { TrieNode* childs[26];//最多26个儿子 string word;//截止到自己这里是否形成的单词,如果只是前缀,则word为空 int count = 0;//所存单词的个数 TrieNode() :word("") { for (auto& child : childs) child = NULL; } }; class Trie { public: TrieNode* root; /** Initialize your data structure here. */ Trie() { root = new TrieNode(); } //三五法则 Trie(const Trie& rhs) { root = new TrieNode(*rhs.root); } //三五法则 Trie& operator = (const Trie& rhs) { if (this != &rhs) { TrieNode* temp = new TrieNode(*rhs.root);//先new再delete,为什么,如果内存不足,new不出来抛出异常,在这就停住了 delete root; //就不会执行delete root,root还可以保持原值 root = temp; } return *this; } //必须要自定义析构函数,因为构造函数new了 ~Trie() { delete root; } /** Inserts a word into the trie. */ void insert(string word) { TrieNode* temp = root; for (char c : word) { int i = c - 'a'; if (temp->childs[i] == NULL) temp->childs[i] = new TrieNode(); else temp = temp->childs[i]; } if(temp->word.empty()) temp->word = word; ++temp->count; } /** Delete a word in the trie. */ bool del(string word)//这个del函数只能删单词,不会删那些前缀的节点 { TrieNode* temp = root; for (char c : word) { int i = c - 'a'; if (temp->childs[i] != NULL) temp->childs[i] = temp->childs[i]; else return false; } if (--temp->count == 0) temp->word = ""; } /** Returns if the word is in the trie. */ bool search(string word) { TrieNode* temp = root; for (char c : word) { int i = c - 'a'; if (temp->childs[i] != NULL) temp = temp->childs[i]; else return false; } return temp->word.size() == word.size(); } };
参考资料:
posted on 2019-03-22 08:19 JoeChenzzz 阅读(490) 评论(0) 编辑 收藏 举报