Trie树
Trie树的个人理解与分析
今天是怠惰的一天,基本完全浪费了。想着这样不行啊。。。今天还没打代码呢。so,学了这个trie树。这个应该是很简单的一个数据结构,但是奈何完全不在状态,写个解析用纸代替大脑记忆,后面忘了回来看看(这更像是一个大脑日志?
一、基本介绍
Trie树又称字典树、单词查找树。是一种能够高效存储和查找字符串集合的数据结构。咋看之下不是很复杂,但是仔细看代码又有点模糊。储存形式如下:
二、用数组来模拟Trie树的具体分析
一图解释:
插入操作代码:
void insert(char *str)
{
int p = 0; //类似指针,指向当前节点
for(int i = 0; str[i]; i++)
{
int u = str[i] - 'a'; //将字母转化为数字
if(!son[p][u]) son[p][u] = ++idx;
//该节点不存在,创建节点,其值为下一个节点位置
p = son[p][u]; //使“p指针”指向下一个节点位置
}
cnt[p]++; //结束时的标记,也是记录以此节点结束的字符串个数
}
查找操作代码:
int query(char *str)
{
int p = 0;
for(int i = 0; str[i]; i++)
{
int u = str[i] - 'a';
if(!son[p][u]) return 0; //该节点不存在,即该字符串不存在
p = son[p][u];
}
return cnt[p]; //返回字符串出现的次数
}
三、835完整代码
//Trie树快速存储字符集合和快速查询字符集合
#include <iostream>
using namespace std;
const int N = 100010;
//son[][]存储子节点的位置,分支最多26条;
//cnt[]存储以某节点结尾的字符串个数(同时也起标记作用)
//idx表示当前要插入的节点是第几个,每创建一个节点值+1
int son[N][26], cnt[N], idx;
char str[N];
void insert(char *str)
{
int p = 0; //类似指针,指向当前节点
for(int i = 0; str[i]; i++)
{
int u = str[i] - 'a'; //将字母转化为数字
if(!son[p][u]) son[p][u] = ++idx; //该节点不存在,创建节点
p = son[p][u]; //使“p指针”指向下一个节点
}
cnt[p]++; //结束时的标记,也是记录以此节点结束的字符串个数
}
int query(char *str)
{
int p = 0;
for(int i = 0; str[i]; i++)
{
int u = str[i] - 'a';
if(!son[p][u]) return 0; //该节点不存在,即该字符串不存在
p = son[p][u];
}
return cnt[p]; //返回字符串出现的次数
}
int main()
{
int m;
cin >> m;
while(m--)
{
char op[2];
scanf("%s%s", &op, &str);
if(*op == 'I') insert(str);
else printf("%d\n", query(str));
}
return 0;
}
四、参考
AcWing算法基础课第二章数据结构(二)