欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

双数组Trie树Java实现-上

时间:2023-06-14

参考链接:

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

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

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。