字典树(基础学习)

来源:互联网 发布:知乎禁止转载 编辑:程序博客网 时间:2024/06/06 07:25

背景和定义:

在算法导论中,Trie并不叫字典树,而是叫基数树,也就是说实际上并不是只是和字符串有关。字典树的构造结果如果说和字符串本身没有关系的话,实际上是一个N叉树。在这个N叉树上,如果是共父节点的N个子节点是有序的,这样构造出来的树实际上就和字典树很像了。


言归正传,我们下面来讨论字典树。字典树的功能实际上是对于很多的串进行压缩,压缩的方法是根据这个字符串的前缀。具体来说,就是说每个字典树的节点将表示一个字符,用从根节点到叶子节点(也有可能是一个中间节点,具体情况见实现情况)来表示一个字符串。


这样做的结果就是实际上压缩了所有模式串,随后在每一次的向下步骤中实际上因为前缀的合并,所以实际上是将前缀

进行了大规模的合并.从而大量的节省了时间.


构造:

我们直接看构造的方法可能更好理解一点.

按照我们前面的说法,首先是我们先加上一个struct的节点:

struct node{node *nxt[26];int flag;node(){for(int i=0;i<26;i++){nxt[i]=NULL;}flag=0;}};

随后我们开始构造字典树,将字典树加在后面的叶子上面:

void ins (char *s){int len=strlen(s);node *now=root;//指向根节点for(int i=0;i<len;i++){int to=s[i]-'a';if(now->nxt[to]==NULL)now->nxt[to]=new node();now=now->nxt[to];//now指向新生成的结点}now->flag++;//最后一个叶节点做标记  意思是这个字符串在这个结点结束}

最后的匹配的结果就是按照root位置向后正常的走


接下里是一个简单的例题:hihocoder 1366


一些技巧和其他类型的问题:
1. 求最短的区别前缀(POJ 2001)
思路非常简单,只要在字典树上记录所有的节点的记录次数,这个时候只要查到一个次数只有1的时候就可以了。

poj2001题解



2. 空间不够导致RE的问题 (BZOJ 1174)
这个题没法交,大家YY吧
题意:给你一个字符集合,你从其中找出一些字符串出来. 希望你找出来的这些字符串的最长公共前缀*字符串的总个数最大化
这道题最要命的不是因为算法困难,而是空间开不下。考虑到我们的Trie本身也是一棵树,也就是说我们可以用建树的方法进行建树,而不是直接开好所有的内存和指针.

推荐博客