字典树 Trie
本文介绍字典树 Trie。
字典树 Trie 的构建
请先看示例:
首先,以 \(0\) 为根。
设插入的字符串为 app。以 \(0\) 为父亲,向下新建一个节点 \(1\),\(0\) 到 \(1\) 的权值为 a。再以 \(1\) 为父亲,向下新建一个节点 \(2\),\(1\) 到 \(2\) 的权值为 p。再以 \(2\) 为父亲,向下新建一个节点 \(3\),\(2\) 到 \(3\) 的权值为 p。
假设插入的字符串为 add。由于以 \(0\) 到 \(1\) 的路径权值为 a,不需要再次新建节点,来到节点 \(1\)。剩下的以此类推。
再插入字符串 but,此时 Trie 树长成这样:

那么,字典树 Trie 的构建就可以描述为,以 \(0\) 为根,以字符串顺序构建,若已存在以当前字符为权的路径,直接跳转。否则,新建节点,并跳转到当前节点。
代码示范
[NOI2000] 单词查找树代码示范:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
struct Trie {
struct point {int dir[26];};
point trie[N];
int tot;
inline void insert (const string &s) {
int p = 0;
for (auto c : s) {
if (!trie[p].dir[c - 'A'])
trie[p].dir[c - 'A'] = ++tot;
//如果没有,新建节点
p = trie[p].dir[c - 'A'];
//跳转,为后续构建准备
}
}
} t;
int main () {
ios :: sync_with_stdio (0);
cin.tie (0), cout.tie (0);
string s;
while (cin >> s)
t.insert (s);
cout << t.tot + 1;
}

浙公网安备 33010602011771号