Trie树_4-TripleArrayTrieTree

Posted searchtosuggest

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Trie树_4-TripleArrayTrieTree相关的知识,希望对你有一定的参考价值。

1、引言

  TripleArrayTrieTree是使用三数组来保存trie树的状态节点和转移条件。

2、实现

  状态节点:

 1 private class Node{
 2     
 3     private Integer base;
 4     private T t;
 5         
 6     public Node() {
 7         // TODO Auto-generated constructor stub
 8     }
 9         
10     public T getT() {
11         return t;
12     }
13         
14     public void setT(T t) {
15         this.t = t;
16     }
17         
18     public Integer getBase() {
19         return base;
20     }
21     public void setBase(Integer base) {
22         this.base = base;
23     }
24 }

  其中t保存着有效值,base保存着该状态节点的转移基数

声明字段:

private List<Node> states =  new ArrayList<>();
private List<Integer> next = new ArrayList<>();
private List<Integer> check = new ArrayList<>();

  其中states中保存着状态节点,next中保存着转移条件,check中用来检测转移的下一个节点是否已经被使用,若被使用,需要改变状态节点的转移基数,来保证状态节点之间的存储不会发生碰撞

构造函数:

1 public TripleArrayTrieTree() {
2     Node root = new Node();
3     root.setBase(128);
4     this.states.add(root);
5 }

  构造函数中,初始化root节点,并加入节点队列中

  三数组的状态为:

status:
states: |0,128,null
next:   
check:

  states中只有根节点,next数组和check数组中暂时没有值

字符串插入:

  

  1 public void insert(String str, T t) {
  2     if(str != null && str.length() > 0) {
  3         byte[] bs = str.getBytes();
  4         int parent = 0;
  5         for(int i = 0; i < bs.length; i ++) {
  6             parent = this.insert(parent, bs[i]);
  7             if(i == bs.length - 1) {
  8                 this.states.get(parent).setT(t);
  9             }
 10         }
 11     }
 12 }
 13     
 14     
 15 private int insert(int parent, byte b) {
 16     int stateBase = this.states.get(parent).getBase();
 17     int nextIndex = stateBase + b;
 18     ensureSize(this.check, nextIndex);
 19     ensureSize(this.next, nextIndex);
 20     Integer parentIndex = this.check.get(nextIndex);
 21         
 22     if(parentIndex == null) {
 23         this.check.set(nextIndex, parent);
 24         Node state = new Node();
 25         state.setBase(128);
 26         this.states.add(state);
 27         int nextStatIndex = this.states.size() - 1;
 28         this.next.set(nextIndex, nextStatIndex);
 29     }else if(parentIndex != parent) {
 30             List<Integer> childIndexs = new LinkedList<>();
 31             int maxIndex = Integer.MIN_VALUE;
 32             for(int i = 0; i < this.check.size(); i++) {
 33                 Integer checkValue = this.check.get(i);
 34                 if(checkValue != null && checkValue == parent) {
 35                     childIndexs.add(i);
 36                     maxIndex = i > maxIndex ? i : maxIndex;
 37                 }
 38             }
 39             maxIndex = nextIndex > maxIndex ? nextIndex : maxIndex;
 40             childIndexs.add(nextIndex);
 41             int offset = this.ensureCheckValid(childIndexs, maxIndex);
 42             this.states.get(parent).setBase(stateBase + offset);
 43             for(int i = 0; i < childIndexs.size() - 1; i++) {
 44                 int originalIndex = childIndexs.get(i);
 45                 this.check.set(originalIndex + offset, parent);
 46                 this.next.set(originalIndex + offset, this.next.get(originalIndex));
 47                 this.check.set(originalIndex, null);
 48             }
 49             nextIndex = nextIndex + offset;
 50             this.check.set(nextIndex, parent);
 51             Node state = new Node();
 52             state.setBase(128);
 53             this.states.add(state);
 54             int nextStatIndex = this.states.size() - 1;
 55             this.next.set(nextIndex, nextStatIndex);    
 56     }
 57         
 58     return this.next.get(nextIndex);
 59 }
 60     
 61 private int ensureCheckValid(List<Integer> list, int maxIndex) {
 62     int offset = 0;
 63     while(true) {
 64         int lastIndex = maxIndex + offset;
 65         ensureSize(this.check, lastIndex);
 66         ensureSize(this.next, lastIndex);
 67         if(this.checkValid(list, offset)) {
 68             break;
 69         }
 70         offset++;
 71     }
 72     return offset;
 73 }
 74     
 75     
 76 private boolean checkValid(List<Integer> list, int offset) {
 77     for(int originalIndex : list) {
 78         if(this.check.get(originalIndex + offset) != null) {
 79             return false;
 80         }
 81     }
 82     return true;
 83 }
 84 
 85 private void ensureSize(List<?> list, int size) {
 86     int originalSize = list.size() - 1;
 87     if(size > originalSize) {
 88         for(int i = 0; i < size - originalSize; i ++) {
 89             list.add(null);
 90         }
 91     }
 92 }
 93 
 94 private List<Integer> getChildren(int parent){
 95     List<Integer> children = new LinkedList<>();
 96     for(int i = 0; i < this.check.size(); i++) {
 97         Integer checkValue = this.check.get(i);
 98         if(checkValue != null && checkValue == parent) {
 99             children.add(this.next.get(i));
100         }
101     }
102     return children;
103 }

  字符串插入的时候比较复杂,主要因为包含了碰撞处理逻辑

  插入字符串:江南大学, 江南, 江边, 南方, 云南 过程中的三数组状态变化:

status:
states: |0,128,null|1,128,null|2,128,null|3,128,null|4,128,null|5,128,null|6,130,null|7,128,null|8,128,null|9,131,null|10,128,null|11,128,null|12,128,江南大学
next:   |0,null|1,null|2,null|3,null|4,null|5,null|6,null|7,null|8,null|9,null|10,null|11,null|12,null|13,5|14,null|15,null|16,null|17,null|18,null|19,null|20,null|21,null|22,null|23,6|24,null|25,null|26,null|27,null|28,null|29,null|30,null|31,3|32,null|33,null|34,null|35,null|36,8|37,null|38,12|39,9|40,null|41,null|42,null|43,null|44,null|45,11|46,null|47,null|48,null|49,2|50,null|51,null|52,null|53,null|54,null|55,null|56,null|57,null|58,null|59,null|60,null|61,null|62,null|63,null|64,null|65,null|66,null|67,null|68,null|69,null|70,null|71,null|72,null|73,null|74,null|75,null|76,null|77,null|78,null|79,null|80,null|81,null|82,null|83,null|84,null|85,null|86,null|87,null|88,null|89,null|90,null|91,null|92,null|93,null|94,null|95,null|96,null|97,null|98,null|99,null|100,null|101,4|102,1|103,7|104,10
check:  |0,null|1,null|2,null|3,null|4,null|5,null|6,null|7,null|8,null|9,null|10,null|11,null|12,null|13,4|14,null|15,null|16,null|17,null|18,null|19,null|20,null|21,null|22,null|23,5|24,null|25,null|26,null|27,null|28,null|29,null|30,null|31,2|32,null|33,null|34,null|35,null|36,7|37,null|38,11|39,8|40,null|41,null|42,null|43,null|44,null|45,10|46,null|47,null|48,null|49,1|50,null|51,null|52,null|53,null|54,null|55,null|56,null|57,null|58,null|59,null|60,null|61,null|62,null|63,null|64,null|65,null|66,null|67,null|68,null|69,null|70,null|71,null|72,null|73,null|74,null|75,null|76,null|77,null|78,null|79,null|80,null|81,null|82,null|83,null|84,null|85,null|86,null|87,null|88,null|89,null|90,null|91,null|92,null|93,null|94,null|95,null|96,null|97,null|98,null|99,null|100,null|101,3|102,0|103,6|104,9

status:
states: |0,128,null|1,128,null|2,128,null|3,128,null|4,128,null|5,128,null|6,130,江南|7,128,null|8,128,null|9,131,null|10,128,null|11,128,null|12,128,江南大学
next:   |0,null|1,null|2,null|3,null|4,null|5,null|6,null|7,null|8,null|9,null|10,null|11,null|12,null|13,5|14,null|15,null|16,null|17,null|18,null|19,null|20,null|21,null|22,null|23,6|24,null|25,null|26,null|27,null|28,null|29,null|30,null|31,3|32,null|33,null|34,null|35,null|36,8|37,null|38,12|39,9|40,null|41,null|42,null|43,null|44,null|45,11|46,null|47,null|48,null|49,2|50,null|51,null|52,null|53,null|54,null|55,null|56,null|57,null|58,null|59,null|60,null|61,null|62,null|63,null|64,null|65,null|66,null|67,null|68,null|69,null|70,null|71,null|72,null|73,null|74,null|75,null|76,null|77,null|78,null|79,null|80,null|81,null|82,null|83,null|84,null|85,null|86,null|87,null|88,null|89,null|90,null|91,null|92,null|93,null|94,null|95,null|96,null|97,null|98,null|99,null|100,null|101,4|102,1|103,7|104,10
check:  |0,null|1,null|2,null|3,null|4,null|5,null|6,null|7,null|8,null|9,null|10,null|11,null|12,null|13,4|14,null|15,null|16,null|17,null|18,null|19,null|20,null|21,null|22,null|23,5|24,null|25,null|26,null|27,null|28,null|29,null|30,null|31,2|32,null|33,null|34,null|35,null|36,7|37,null|38,11|39,8|40,null|41,null|42,null|43,null|44,null|45,10|46,null|47,null|48,null|49,1|50,null|51,null|52,null|53,null|54,null|55,null|56,null|57,null|58,null|59,null|60,null|61,null|62,null|63,null|64,null|65,null|66,null|67,null|68,null|69,null|70,null|71,null|72,null|73,null|74,null|75,null|76,null|77,null|78,null|79,null|80,null|81,null|82,null|83,null|84,null|85,null|86,null|87,null|88,null|89,null|90,null|91,null|92,null|93,null|94,null|95,null|96,null|97,null|98,null|99,null|100,null|101,3|102,0|103,6|104,9

status:
states: |0,128,null|1,128,null|2,128,null|3,132,null|4,128,null|5,128,null|6,130,江南|7,128,null|8,128,null|9,131,null|10,128,null|11,128,null|12,128,江南大学|13,128,null|14,128,null|15,128,江边
next:   |0,null|1,null|2,null|3,null|4,null|5,null|6,null|7,null|8,null|9,null|10,null|11,null|12,null|13,5|14,null|15,null|16,null|17,null|18,null|19,null|20,null|21,null|22,null|23,6|24,null|25,null|26,null|27,null|28,null|29,null|30,null|31,3|32,null|33,null|34,null|35,null|36,8|37,null|38,12|39,9|40,null|41,null|42,null|43,null|44,null|45,11|46,null|47,null|48,null|49,2|50,null|51,null|52,null|53,null|54,null|55,null|56,null|57,15|58,null|59,null|60,null|61,null|62,14|63,null|64,null|65,null|66,null|67,null|68,null|69,null|70,null|71,null|72,null|73,null|74,null|75,null|76,null|77,null|78,null|79,null|80,null|81,null|82,null|83,null|84,null|85,null|86,null|87,null|88,null|89,null|90,null|91,null|92,null|93,null|94,null|95,null|96,null|97,null|98,null|99,null|100,null|101,4|102,1|103,7|104,10|105,4|106,null|107,null|108,13
check:  |0,null|1,null|2,null|3,null|4,null|5,null|6,null|7,null|8,null|9,null|10,null|11,null|12,null|13,4|14,null|15,null|16,null|17,null|18,null|19,null|20,null|21,null|22,null|23,5|24,null|25,null|26,null|27,null|28,null|29,null|30,null|31,2|32,null|33,null|34,null|35,null|36,7|37,null|38,11|39,8|40,null|41,null|42,null|43,null|44,null|45,10|46,null|47,null|48,null|49,1|50,null|51,null|52,null|53,null|54,null|55,null|56,null|57,14|58,null|59,null|60,null|61,null|62,13|63,null|64,null|65,null|66,null|67,null|68,null|69,null|70,null|71,null|72,null|73,null|74,null|75,null|76,null|77,null|78,null|79,null|80,null|81,null|82,null|83,null|84,null|85,null|86,null|87,null|88,null|89,null|90,null|91,null|92,null|93,null|94,null|95,null|96,null|97,null|98,null|99,null|100,null|101,null|102,0|103,6|104,9|105,3|106,null|107,null|108,3

status:
states: |0,128,null|1,128,null|2,128,null|3,132,null|4,128,null|5,128,null|6,130,江南|7,128,null|8,128,null|9,131,null|10,128,null|11,128,null|12,128,江南大学|13,128,null|14,128,null|15,128,江边|16,129,null|17,129,null|18,132,null|19,128,null|20,129,null|21,128,南方
next:   |0,null|1,null|2,null|3,null|4,null|5,null|6,null|7,null|8,null|9,null|10,null|11,null|12,null|13,5|14,17|15,null|16,null|17,null|18,null|19,null|20,null|21,null|22,20|23,6|24,18|25,null|26,null|27,null|28,null|29,null|30,null|31,3|32,null|33,null|34,null|35,null|36,8|37,null|38,12|39,9|40,null|41,null|42,null|43,null|44,null|45,11|46,null|47,null|48,null|49,2|50,null|51,null|52,null|53,null|54,null|55,null|56,null|57,15|58,21|59,null|60,null|61,null|62,14|63,null|64,null|65,null|66,null|67,null|68,null|69,null|70,null|71,null|72,null|73,null|74,null|75,null|76,null|77,null|78,null|79,null|80,null|81,null|82,null|83,null|84,null|85,null|86,null|87,null|88,null|89,null|90,null|91,null|92,null|93,null|94,null|95,null|96,null|97,null|98,null|99,null|100,null|101,16|102,1|103,7|104,10|105,4|106,19|107,null|108,13
check:  |0,null|1,null|2,null|3,null|4,null|5,null|6,null|7,null|8,null|9,null|10,null|11,null|12,null|13,4|14,16|15,null|16,null|17,null|18,null|19,null|20,null|21,null|22,19|23,5|24,17|25,null|26,null|27,null|28,null|29,null|30,null|31,2|32,null|33,null|34,null|35,null|36,7|37,null|38,11|39,8|40,null|41,null|42,null|43,null|44,null|45,10|46,null|47,null|48,null|49,1|50,null|51,null|52,null|53,null|54,null|55,null|56,null|57,14|58,20|59,null|60,null|61,null|62,13|63,null|64,null|65,null|66,null|67,null|68,null|69,null|70,null|71,null|72,null|73,null|74,null|75,null|76,null|77,null|78,null|79,null|80,null|81,null|82,null|83,null|84,null|85,null|86,null|87,null|88,null|89,null|90,null|91,null|92,null|93,null|94,null|95,null|96,null|97,null|98,null|99,null|100,null|101,0|102,0|103,6|104,9|105,3|106,18|107,null|108,3

status:
states: |0,128,null|1,128,null|2,128,null|3,132,null|4,128,null|5,128,null|6,130,江南|7,128,null|8,128,null|9,131,null|10,128,null|11,128,null|12,128,江南大学|13,128,null|14,128,null|15,128,江边|16,129,null|17,129,null|18,132,null|19,128,null|20,129,null|21,128,南方|22,129,null|23,128,null|24,134,null|25,130,null|26,130,null|27,128,云南
next:   |0,null|1,null|2,null|3,null|4,null|5,null|6,null|7,null|8,null|9,null|10,null|11,null|12,null|13,5|14,17|15,26|16,null|17,24|18,null|19,null|20,null|21,null|22,20|23,6|24,18|25,27|26,null|27,null|28,null|29,null|30,null|31,3|32,null|33,null|34,null|35,null|36,8|37,null|38,12|39,9|40,null|41,null|42,null|43,null|44,null|45,11|46,null|47,null|48,null|49,2|50,null|51,null|52,null|53,null|54,null|55,null|56,null|57,15|58,21|59,23|60,null|61,null|62,14|63,null|64,null|65,null|66,null|67,null|68,null|69,null|70,null|71,null|72,null|73,null|74,null|75,null|76,null|77,null|78,null|79,null|80,null|81,null|82,null|83,null|84,null|85,null|86,null|87,null|88,null|89,null|90,null|91,null|92,null|93,null|94,null|95,null|96,null|97,null|98,null|99,null|100,22|101,16|102,1|103,7|104,10|105,4|106,19|107,25|108,13
check:  |0,null|1,null|2,null|3,null|4,null|5,null|6,null|7,null|8,null|9,null|10,null|11,null|12,null|13,4|14,16|15,25|16,null|17,23|18,null|19,null|20,null|21,null|22,19|23,5|24,17|25,26|26,null|27,null|28,null|29,null|30,null|31,2|32,null|33,null|34,null|35,null|36,7|37,null|38,11|39,8|40,null|41,null|42,null|43,null|44,null|45,10|46,null|47,null|48,null|49,1|50,null|51,null|52,null|53,null|54,null|55,null|56,null|57,14|58,20|59,22|60,null|61,null|62,13|63,null|64,null|65,null|66,null|67,null|68,null|69,null|70,null|71,null|72,null|73,null|74,null|75,null|76,null|77,null|78,null|79,null|80,null|81,null|82,null|83,null|84,null|85,null|86,null|87,null|88,null|89,null|90,null|91,null|92,null|93,null|94,null|95,null|96,null|97,null|98,null|99,null|100,0|101,0|102,0|103,6|104,9|105,3|106,18|107,24|108,3

 

字符串查询:

 1 public T search(String str) {
 2     if(str != null && str.length() > 0) {
 3         int parent = 0;
 4         byte[] bs = str.getBytes();
 5         for(int i = 0; i < bs.length; i++) {
 6             parent = this.search(parent, bs[i]);
 7         }
 8         if(parent > 0) {
 9             return this.states.get(parent).getT();
10         }
11     }
12     return null;
13 }
14     
15     
16 private int search(int parent, byte b){
17     if(parent >= 0 && parent < this.states.size()) {
18         int nextIndex = this.states.get(parent).getBase() + b;
19         if(nextIndex < this.check.size() && this.check.get(nextIndex) == parent) {
20             return this.next.get(nextIndex);
21         }
22     }
23     return -1;
24 }

  查询的时候比较简单

3、总结

  TripleArrayTrieTree使用三个数组来实现trie树,可以明显的降低内存开销,同时并未降低查询效率,但是在字符串插入的时候,为了解决节点碰撞问题,会增加大量的时间消耗

参考:https://github.com/pythonerleilei/Search/blob/master/src/seach/data_structure/tree/impl/TripleArrayTrieTree.java

以上是关于Trie树_4-TripleArrayTrieTree的主要内容,如果未能解决你的问题,请参考以下文章

Trie树_3-MapBaseTrieTree

Trie树_4-TripleArrayTrieTree

Trie树_5-DoubleArrayTrieTree

BZOJ_3012_[Usaco2012 Dec]First!_trie树+拓扑排序

PHP 生成 Trie 树

[H字典树] lc1938. 查询最大基因差(trie总结+dfs离线搜索+离线处理+周赛250_4)