算法笔记——字典树

字典树是用于字符串快速检索的多叉树,每个节点都包含多个字符指针,将从根节点到某一节点路径上经过的字符连接起来,为该节点对应的字符串

 字典树基本操作:创建、查找、插入和删除,极少出现删除操作。

字典树的创建和插入

用trie[][]两维数组来存储字典树,第一维表示节点号,第二维表示字符种类,以小写字符组成的字符串为例,trie第二维大小为26。每次遇到空节点则赋上新节点号并记录索引,然后将p指针指向新节点。以bool数组end来标记某节点是否是单词结尾。

int tot=1;//注意tot初值为1
void insert(string s)
{
    int len=s.length(),p=1;
    for(int i=0;i<len;i++)
    {
        int ch=s[i]-'a';
        if(!trie[p][ch])
            trie[p][ch]=++tot;
        p=trie[p][ch];
    }
    end[p]=true;
}

字典树查找

以同样索引的方式查找,如果查找位置为0,则说明不存在,当字符串处理完毕后,判断末尾有无单词结束标记,若有,说明该字符串存在。

bool search(string s)
{
    int len=s.length(),p=1;
    for(int i=0;i<len;i++)
    {
        int ch=s[i]-'a';
        p=trie[p][ch];
        if(!p)    return false;
    }
    return end[p];
}

算法分析

在字典树中查找一个关键字的时间与树中包含的节点数无关,至于关键字的字符数有关。若查找的字符串长度为n,则查找的时间复杂度均为O(n)

若单词总长度为N,字符的种类为k,插入的字符串长度为n,则创建Trie的复杂度为O(N),空间复杂度为O(Nk),插入字符串的时间复杂度均为O(n)

字典树的应用

(1)字符串检索。事先将已知的一些字符串(字典)的有关信息存储到trie树里,查找一些字符串是否出现过、出现的频率和搜索引擎的热门查询。

(2)前缀统计。统计一个串所有前缀单词的个数,只需统计从根到叶子路径上单词出现的个数,也可以判断一个单词是否是另一个单词的前缀。

(3)最长公共前缀。trie数利用多个字符串的公共前缀来节省存储空间, 反之,当把大量字符串都存储到一棵trie树上时,可以快速得到某些字符串的公共前缀。对所有字符串都建立字典树,两个串的最长公共前缀的长度就是他们所在节点最近公共祖先的长度,于是转化为lca问题。

(4)排序。利用字典树进行串排序。例如,给定N个互不相同的仅由一个单词构成的英文名,将他们按字典序从小到大输出。采用数组方式创建字典树,这棵树每个节点的所有子节点都按照其字母大小排序。对字典树进行先序遍历,输出的相应字符串便是按字典序排序的结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值