双数组Trie树(DoubleArrayTrie)Java实现-上

参考链接:

https://segmentfault.com/a/1190000008877595

双数组字典树(DATrie)详解及实现 | Ragty の Blog

双数组Trie树(DoubleArrayTrie)Java实现-码农场

之前node实现方式

开场白:

        看了好几天了,感觉自己菜的不行,懂了之后写代码又发现很多问题,把一个树放到数组里也不是那么容易的,但想想还是先总结一版,后面再优化。

 双数组实现Trie:

        就是用两个数组维护一棵树,通过计算能找到对应的子节点。

双数组有哪些:

        base数组,用于记录偏移量,check数组,用于记录上一个节点的数组下标,用于验证。

关键点思考:

        如何创建双数组结构的Trie

        1  base 中的值:base中存储的是偏移量,偏移量加上下一个字符的char或者编号,就是下一个base节点的下标

        2 如何找叶子节点?:通过base中的下标,加上下一个查找字符的char值或者唯一编号,就能得到叶子节点的下标。

        3 如何避免解决base冲突:当构建的时候,偏移量+字符char找到的下一个叶子节点下标很有可能已经被占用了,这个时候通过改变偏移量(自增+1)来继续寻找直到找到。

        4 多个叶子节点:多个叶子节点构建的时候需要保证不同的字符char+偏移量 对应的base数组下标都是空的才可以,有任何一个位置被占了都要偏移量+1来继续寻找,所以构建的时候按层构建Tire前缀树,需要传入构建前缀树的词是按照每个字符排序过的。

        5 如何表达结束:当base中的值为负值,代表当前有一个词结尾了,查询的时候用于判断。

        6 check数组:check数组中存的是上一个父节点base的下标,因为通过偏移量+字符char的方式,不能保证命中的就是当前父节点的子节点,需要check来验证一下

        如何查找

        循环要查找的字符,根据每个字符+base[i],来计算下一个节点的地址,并根据下一个节点check来检查,当base[i]的值为 负值,说明有一个词结尾,就输出,直到最后找不到叶子节点或者词结束。

        缺点,只能找出 查找字符前面的词,后面的叶子节点关联不出来,因为需要有字符才能计算后面的叶子节点。

        双数组Trie的优点:查找匹配时间复杂度0(m)  m是要查找字符的长度

         双数组Trie的缺点:

                        1 构建时间比较长,因为会有冲突再找的过程     

                        2 数组浪费比较严重不可控,有可能还要扩容

                        3 不好添加删除节点,添加很有可能会有冲突,导致当前层所有子节点的位置都要重算,包括当前层下面所有叶子节点,严重有可能要重新构建整棵树。

总结:在网上看了很多帖子,也看了几版代码,还是没有吃透,自己写的时候发现很多问题,所以继续学习吧,关键点先总结下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值