Tire树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。
说白了,就是一棵大树,这棵树的每个除了根节点的结点都存储了一个字符。
说在前面
字典树有两种实现方式,一种是利用指针实现,也就是一个实实在在的二十六叉树;另一种就是利用数组实现。(在这里分别称之为指针版字典树和数组版字典树)
两种实现方式各有优劣,指针版本的清晰明了,空间占用率相对较小(空间占用小就可以用剩下的空间干其他很多事);而数组版字典树就是一次性把空间开好了,比较方便。
指针版字典树
结构体定义:
#define datatype int
typedef struct node{
bool isEnd;
datatype data; //一般是计数
struct node *letter[27];
}Node,*List;
新建一个结点的初始化:
List Initial(){
List p = (List)malloc(sizeof(Node));
memset(p,0,sizeof(Node));
p->isEnd = false;
return p;
}
当然,一种更加推荐的方式是使用calloc()
函数,malloc()
有更多自己操控的空间
List Initial(){
List p = (List)calloc(sizeof(Node));
return p;
}
创建一棵Trie
:
#define MAXSIZE 1000
void createStopTrie(List *root, FILE *in) {
int pos = 0;
int len = fread(buffer, sizeof(char), MAXSIZE, in);
char ch;
int depth = 0;
List end = *root;
while (pos < len) {
ch = tolower(buffer[pos]);
if (islower(ch)) {
if (end->letter[ch - 'a'] == NULL) {
end->letter[ch - 'a'] = Initial();
}
end = end->letter[ch - 'a'];
pos++;
depth++;
} else {
end->isEnd = true;
pos++;
end = *root;
if (depth > Depth) Depth = depth;
depth = 0;
}
}
}
调用前需要
Root = Initial();
createArticleTrie(&Root,fp);
三个基本性质:
- 根节点不包含字符,除根节点的每一个节点都只包含一个字符。
- 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
- 每个节点的所有子节点包含的字符都不相同
我觉得这个像是一个26叉树,也有一点想26进制的一个东西。
我们这里存储的都是小写字母,如果包含又大写字母的话可能就是一个52叉树了。一般不会出现这种情况吧,出现了也不怪我
主要实现单词的高效存储与高效查找
利用cout[i]
来记录以i
为编号的字符结尾的字符串的个数。
就有两个基本操作
#include <stdio.h>
const int N = 1e5 + 5;
int tr[N][27], cou[N], idx;
char str[N];
void insert(char *s)
{
int p = 0;
for (int i = 0; s[i]; i++)
{
int u = (s[i] - 'a');
if (!tr[p][u])
tr[p][u] = ++idx;
p = tr[p][u];
}
cou[p]++;
}
int query(char *s)
{
int p = 0;
for (int i = 0; s[i]; i++)
{
int u = (s[i] - 'a');
if (!tr[p][u])
return 0;
p = tr[p][u];
}
return cou[p];
}
参考资料:
- https://blog.csdn.net/forever_dreams/article/details/81009580
- https://zhuanlan.zhihu.com/p/28891541
- https://blog.csdn.net/weixin_42815609/article/details/102692411
- 用C++讲得很清楚:https://blog.csdn.net/weixin_44176696/article/details/104716191
- 这个有头文件诶,高级!:https://blog.csdn.net/A951860555/article/details/108716487