键树是有根有序树,每个节点均包含r个分支,深度为d的节点分别对应于长度为d的字符串,且祖先所对应字符串必为后代所对应字符串前缀。
#include<iostream>
#include<string>
using namespace std;
#define TrieNodePos TrieNode*
class TrieNode {//键树节点
public:
TrieNodePos next[26];//子节点指针
int flag[26];//26个字母标志位
int size;
TrieNode() {
memset(flag, 0, sizeof(flag));
memset(next, NULL, sizeof(next));
size = 0;
}
};
class TrieTree {
public:
TrieNodePos root;//键树根
int size;
TrieTree() {
root = new TrieNode();
size = 0;
}
void insert(string dt) {
TrieNodePos pr = root;//记录父节点
TrieNodePos cur = root;
int n = dt.length();
for (int i = 0; i < n; i++) {
if (cur == NULL) {//如果节点尚未被创建
cur = new TrieNode();
pr->next[dt[i - 1] - 97] = cur;//将父节点指向子节点
}
if (cur->flag[dt[i] - 97] == 0) {//字母尚未有标识
cur->flag[dt[i] - 97] = 1;
}
pr = cur;
if (i < n - 1) {//指向下一个子节点
cur = cur->next[dt[i] - 97];
}
}
size++;
}
bool find(string dt) {//查找
TrieNodePos cur = root;
int n = dt.length();
for (int i = 0; i < n; i++) {
if (cur == NULL || cur->flag[dt[i] - 97] == 0) return false;//只要有不同,或者当前节点为空,就返回查找失败
if (i < n - 1) cur = cur->next[dt[i + 1] - 97];
}
return true;
}
void traverse(string pr,TrieNodePos x) {//遍历
for (int i = 0; i < 26; i++) {
if (x->flag[i] == 1) {
if (x->next[i] != NULL) traverse(pr + char(i + 97), x->next[i]);//只要还有子节点
else cout << pr + char(i + 97) << " ";//到叶节点,则输出
}
}
}
};
int main() {
TrieTree tree;
tree.insert("what");
tree.insert("is");
tree.insert("your");
tree.insert("problem");
tree.traverse("", tree.root);
}