trie树 模板

75 阅读2分钟

视频:第二章 数据结构(二) - AcWing

trie树:时间复杂度O(n),n是树的宽度

trie树用来存储和查找字符串的数据结构。

建树

输入一个字符,如果该字符之前没出现过,那么就顺着原路径建立新的节点来存储该字符,否则,另辟蹊径,重新开分支路径建立节点来存储字符。直达字符串全部建立完为止。

image.png

模板题

835. Trie字符串统计 - AcWing题库

#include<iostream>
using namespace std;
const int N=100010;
int son[N][26];//每行代表一个节点,每列代表一个字符
int cnt[N];//存储以特定节点结尾的字符串的计数
int idx;  ////表示当前要插入的节点是第几个,每创建一个节点值+1
char str[N];

//插入
void insert(char str[])
{
    int p=0;//根节点,为0
    for(int i=0;str[i];i++)
    {
        int u=str[i]-'a';  //给26个字母建立映射,从0到26
        if(!son[p][u])son[p][u]=++idx;  //如果p节点不存在u这个儿子,那么就创建u这个儿子
        p=son[p][u];  //执行下一个节点
    }
    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];//返回以p结尾的单词数量
}

int main()
{
    
    int n;
    scanf("%d",&n);//输入n行
  
    while(n--)
    {  
        char op[2];//op[0]存实际数据,op[1]存"/n"
    
        scanf("%s%s",op,str);//先读入操作类型,再读入要操作的字符串
        if(op[0]=='I')insert(str);//如果输入的操作数是I,那就进行插入
        else printf("%d\n",query(str));//否则输入的就是Q,就把查询结果打印出来
    }
    
    return 0;
}

image.png