Trie树
字典树,前缀树,单词查找树
应用:1)字符串检索 2)字符串最长公共前缀 3)英文单词的排序 4)作为其他数据结构和算法的辅助结构
结构图
下面我们有and,as,at,cn,com这些关键词,那么如何构建trie树呢?下图是Trie的一种
节点存储内容:
- 只存是不是单词的标识,用于对已知字符串匹配
- 存储单个字母,用来查询或获取单词
特性
- 根节点不包含字符,除根节点外的每一个子节点都包含一个字符或者标识
- 从根节点到某一节点,路径上经过的字符连接起来,就是该节点对应的字符串(针对于节点存储内容的第2种情况,其余情况不一定)
- 兄弟节点的前缀单词都相同
C++代码,节点只存储是否结束
#include <vector>
#include <string>
using namespace std;
class TrieNode {
public:
TrieNode* next[26];
bool isWord;
// Initialize your data structure here.
TrieNode() :isWord{false} {
memset(next, 0, sizeof(next));
};
};
class Trie {
public:
Trie() {
root = new TrieNode();
}
// Inserts a word into the trie.
void insert(string word) {
TrieNode* p = root;
int len = word.length();
for (int i = 0; i < len; i++){
char c = word[i];
int index = c - 'a';
if(p->next[index]==NULL) p->next[index] = new TrieNode();
p = p->next[index];
}
p->isWord = true;
}
// Returns if the word is in the trie.
bool search(string word) {
TrieNode* p = root;
int len = word.length();
for (int i = 0; i < len&&p; i++){
p = p->next[word[i]-'a'];
}
return p&&p->isWord;
}
// Returns if there is any word in the trie
// that starts with the given prefix.
bool startsWith(string prefix) {
TrieNode* p = root;
int len = prefix.length();
for (int i = 0; i < len&&p; i++){
p = p->next[prefix[i] - 'a'];
}
return p;
}
private:
TrieNode* root;
};
// Your Trie object will be instantiated and called as such:
// Trie trie;
// trie.insert("somestring");
// trie.search("key");
Java代码,节点存储字母
class TrieNode {
// Initialize your data structure here.
char val;
boolean isEnd=false;
TrieNode[] children=new TrieNode[26];
public TrieNode() {}
public TrieNode(char val) {
this.val=val;
}
}
public class Trie {
private TrieNode root;
public Trie() {
root = new TrieNode();
}
// Inserts a word into the trie.
public void insert(String word) {
TrieNode index=root;
char[] words=word.toCharArray();
for(int i=0,len=words.length;i<len;++i){
if(index.children[words[i]-'a']!=null){
index=index.children[words[i]-'a'];
}else{
TrieNode node=new TrieNode(words[i]);
index.children[words[i]-'a']=node;
index=node;
}
}
index.isEnd=true;
}
// Returns if the word is in the trie.
public boolean search(String word) {
TrieNode index=root;
char[] words=word.toCharArray();
for(int i=0,len=words.length;i<len;++i){
if(index.children[words[i]-'a']!=null){
index=index.children[words[i]-'a'];
}else{
return false;
}
}
return index.isEnd?true:false;
}
// Returns if there is any word in the trie
// that starts with the given prefix.
public boolean startsWith(String prefix) {
TrieNode index=root;
char[] words=prefix.toCharArray();
for(int i=0,len=words.length;i<len;++i){
if(index.children[words[i]-'a']!=null){
index=index.children[words[i]-'a'];
}else{
return false;
}
}
return true;
}
}