Trie树通过树形结构高效实现字符串前缀匹配与查找。1. 每个节点包含26个子节点指针和一个结尾标记;2. 插入时逐字符创建路径,末尾标记isEnd;3. 查找需完整匹配且isEnd为true;4. 前缀判断只需路径存在;5. 封装为类便于操作,适用于自动补全等场景。

实现一个 Trie 树(字典树)在 C++ 中非常实用,尤其适用于字符串前缀匹配、自动补全、拼写检查等场景。Trie 树通过将字符串逐字符存储在树结构中,能高效地插入、查找和匹配具有相同前缀的单词。
每个 Trie 节点包含若干子节点指针和一个标记,表示该节点是否为某个字符串的结尾。
class TrieNode {
public:
bool isEnd;
TrieNode* children[26]; // 假设只处理小写字母 a-z
<pre class="brush:php;toolbar:false;"><pre class="brush:php;toolbar:false;">TrieNode() {
isEnd = false;
for (int i = 0; i < 26; ++i) {
children[i] = nullptr;
}
}};
这里使用大小为 26 的指针数组来映射 'a' 到 'z'。也可以用 unordered_map<char, TrieNode*> 来支持更多字符类型,更灵活但稍慢。
从根节点开始,对字符串中每个字符,计算其在数组中的索引(如 c - 'a'),若对应子节点不存在则创建新节点。遍历完所有字符后,将最后一个节点的 isEnd 设为 true。
立即学习“C++免费学习笔记(深入)”;
void insert(TrieNode* root, const string& word) {
TrieNode* node = root;
for (char c : word) {
int idx = c - 'a';
if (!node->children[idx]) {
node->children[idx] = new TrieNode();
}
node = node->children[idx];
}
node->isEnd = true;
}
与插入类似,逐字符向下走。如果中途遇到空指针,说明字符串不存在;若能走完且最后一个节点的 isEnd 为 true,则存在该字符串。
bool search(TrieNode* root, const string& word) {
TrieNode* node = root;
for (char c : word) {
int idx = c - 'a';
if (!node->children[idx]) {
return false;
}
node = node->children[idx];
}
return node->isEnd;
}
只需要检查能否顺着前缀的每个字符走到最后,不要求 isEnd 为 true。
bool startsWith(TrieNode* root, const string& prefix) {
TrieNode* node = root;
for (char c : prefix) {
int idx = c - 'a';
if (!node->children[idx]) {
return false;
}
node = node->children[idx];
}
return true;
}
把上面功能封装成一个类会更清晰:
class Trie {
private:
TrieNode* root;
<p>public:
Trie() {
root = new TrieNode();
}</p><pre class="brush:php;toolbar:false;"><pre class="brush:php;toolbar:false;">void insert(const string& word) {
TrieNode* node = root;
for (char c : word) {
int idx = c - 'a';
if (!node->children[idx]) {
node->children[idx] = new TrieNode();
}
node = node->children[idx];
}
node->isEnd = true;
}
bool search(const string& word) {
TrieNode* node = root;
for (char c : word) {
int idx = c - 'a';
if (!node->children[idx]) {
return false;
}
node = node->children[idx];
}
return node->isEnd;
}
bool startsWith(const string& prefix) {
TrieNode* node = root;
for (char c : prefix) {
int idx = c - 'a';
if (!node->children[idx]) {
return false;
}
node = node->children[idx];
}
return true;
}};
使用示例:
Trie trie;
trie.insert("apple");
cout << trie.search("apple") << endl; // 输出 1
cout << trie.search("app") << endl; // 输出 0
cout << trie.startsWith("app") << endl; // 输出 1
基本上就这些。注意实际项目中需考虑内存释放问题,可在析构函数中递归删除所有节点。Trie 在处理大量字符串前缀时效率远高于哈希表,虽然空间开销略大,但在搜索性能上有明显优势。
以上就是C++怎么实现一个Trie树(字典树)_C++数据结构与前缀匹配算法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号