字典树又称前缀树,由多叉树形成主要包含如下2个部分:
- 儿子数组:用于存储下一个节点(若字符集为’a’-‘z’:则儿子数组大小则为26,即最多为26叉树)
- 结尾标识符
- 方法
- 插入(重点)
- 查找
主要内容
字典树实现比较简单,最主要的便是【插入】的编写,如下将用代码实例结合图结构来讲解一下字典树
字典树主要有3个性质:
- 根节点不包含字符,除根节点外每一个节点都只包含一个字符
- 从根节点到某一节点,路径上经过的字符连起来,为该节点对应的字符串
- 每个节点的所有子节点包含的字符串都不相同
算法思路:
- 数据结构:
树上每个节点均由【儿子数组】和【结尾符】组成。 算法
- 插入
- 按字母遍历单词
- 判定当前字母是否在儿子数组中
- 是,则继续递归遍历
- 否,创建新结点,按i继续操作
- 知道遍历到最后一个字母,将该字母对应的节点【结尾符】置真!
/* 实例代码为一个单词字典树 */
#include <vector>
#include <string>
using namespace std;
class Trie {
bool isEnd;
vector<Trie*> children;
/* 查找 */
Trie* searchPrefix(string& prefix){
Trie* node = this;
for (char ch : prefix) {
ch -= 'a';
if (node->children[ch] == nullptr) {
return nullptr;
}
node = node->children[ch];
}
return node;
}
public:
Trie() :
isEnd(false),children(26,nullptr){}
/* 插入 */
void insert(string& word) {
Trie* cur = this;
for (auto ch : word) {
ch-='a';
if (cur->children[ch] == nullptr) {
cur->children[ch] = new Trie();
}
cur = cur->children[ch];
}
cur->isEnd = true;
}
/* 查找 */
bool search(string& word){
Trie* node=searchPrefix(word);
return node!=nullptr && node->isEnd;
}
};
复杂度分析
时间复杂度:
- 空间复杂度: