Trie树是一种空间换时间的字典树,我自己一般叫它为26叉树,还有一种类似的树是 三叉树 ,可以用来做自动补全算法,这项算法可以用来做搜索引擎的自动搜索补全功能。
下面仅仅 以我自己对Trie树的理解来看看Trie树是什么神奇的结构?
我们以一下的字符串来构造一颗Trie树,
abc,
abcd,
abd,
b,
bcd,
efg,
hij,
这就是Trie树的结构,红色的节点数表示的是给定的字符串的个数,从根到红色的节点表示的是一个完整的字符串,并且每个节点有26个子节点,所以就不难写出下面的这段代码:
#include<iostream>
using namespace std;
struct TNode {
bool isTerminal;
TNode *child[26];
int count; //这个字段表示在给定的字符串数组中,以当前这个节点为结尾的字符串为前缀的字符串的个数
TNode() {
isTerminal = false;
count = 0;
for (int i = 0; i < 26; i++) {
child[i] = NULL;
}
}
};
//向这棵树中插入一个字符串
void insert(const char *str, TNode *root) {
TNode *head = root;
int pos = 0;
while (*str != '\0') {
pos = *str - 'a'; //按照顺序给子孩子排列
if (head->child[pos] == NULL) {
head->child[pos] = new TNode();
}
head = head->child[pos];
str++;
head->count = head->count + 1; //以当前字符串为前缀的字符串的个数
}
head->isTerminal = true; //到了最后一个字符串才是表示这是个完整的字符串
}
//查找给定的字符串是不是在这棵树中
int search(const char *str, TNode *root) {
TNode *head = root;
int pos;
while (*str != '\0') {
pos = *str - 'a';
if (head->child[pos] == NULL) {
return 0;
}
head = head->child[pos];
str++;
}
if (head->isTerminal)
return 1;
else
return 0;
}
//在树种查找str为前缀的字符串的个数
int calcuCount(const char *str, TNode *root) {
TNode *head = root;
int pos = 0;
while (*str != '\0') {
pos = *str - 'a';
if (head->child[pos] != NULL)
head = head->child[pos];
str++;
}
return head->count;
}
int main() {
const char *arr[] = {"abc", "abcd", "abch", "b", "bcd", "efg", "hij"};
TNode *root = new TNode();
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
insert(arr[i], root);
}
cout << search("abc", root) << endl;
cout << calcuCount("abc", root) << endl;
return 0;
}
基于上述的数据结构,来看看 hihicoder上的一道题:http://hihocoder.com/problemset/problem/1014 , 题目的意思很明确