前缀树的构建
- 利用数组构建
// change this value to adapt to different cases
#define N 26
struct TrieNode {
TrieNode* children[N];
// you might need some extra values according to different cases
};
/** Usage:
* Initialization: TrieNode root = new TrieNode();
* Return a specific child node with char c: (root->children)[c - 'a']
*/
class TrieNode{ // 前缀树节点的实现
public:
TrieNode* children[26]; // 前缀树可以存储26个小写字母,存在next数组中。
bool flage;
TrieNode() { // 构造函数
memset(children, NULL, sizeof(children)); // 分配空间
flage = false;
}
~TrieNode() { // 析构函数。此处可以不写,实际中写上较好。
for (int i = 0; i < 26; i++) {
if(children[i]) delete children[i];
}
}
};
访问子节点更加快捷,且容易,但并非所有子节点都会用到,会造成空间的浪费。
- 利用哈希表构建
struct TrieNode {
unordered_map<char, TrieNode*> children;
// you might need some extra values according to different cases
};
/** Usage:
* Initialization: TrieNode root = new TrieNode();
* Return a specific child node with char c: (root->children)[c]
*/
访问子节点更加容易,但速度稍慢,但方法较为灵活,不会收到固定长度、范围的限制。
前缀树的插入
Initialize: cur = root
for each char c in target string S:
if cur does not have a child c:
cur.children[c] = new Trie node
cur = cur.children[c]
cur is the node which represents the string S
前缀树的搜索
Initialize: cur = root
for each char c in target string S:
if cur does not have a child c:
search fails
cur = cur.children[c]
search successes
前缀树的实现
struct TrieNode {
bool flag;
map<char, TrieNode*> next;
};
class Trie {
private:
TrieNode* root;
public:
/** Initialize your data structure here. */
Trie() {
root = new TrieNode();
}
/** Inserts a word into the trie. */
void insert(string word) {
TrieNode* p = root;
for (int i = 0; i < word.length(); ++i) {
if ((p->next).count(word[i]) <= 0) {
// insert a new node if the path does not exist
(p->next).insert(make_pair(word[i], new TrieNode()));
}
p = (p->next)[word[i]];
}
p->flag = true;
}
/** Returns if the word is in the trie. */
bool search(string word) {
TrieNode* p = root;
for (int i = 0; i < word.length(); ++i) {
if ((p->next).count(word[i]) <= 0) {
return false;
}
p = (p->next)[word[i]];
}
return p->flag;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix) {
TrieNode* p = root;
for (int i = 0; i < prefix.length(); ++i) {
if ((p->next).count(prefix[i]) <= 0) {
return false;
}
p = (p->next)[prefix[i]];
}
return true;
}
};
/**
* 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);
*/