Trie树_5-DoubleArrayTrieTree
Posted searchtosuggest
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Trie树_5-DoubleArrayTrieTree相关的知识,希望对你有一定的参考价值。
1、引言
DoubleArrayTrieTree是使用双数组来保存状态节点和状态转移条件
2、实现
状态节点:
1 private class Node{ 2 3 private int base = 128; 4 private T t; 5 6 public Node() { 7 // TODO Auto-generated constructor stub 8 } 9 10 public int getBase() { 11 return base; 12 } 13 14 public void setBase(int base) { 15 this.base = base; 16 } 17 18 public T getT() { 19 return t; 20 } 21 22 public void setT(T t) { 23 this.t = t; 24 } 25 26 @Override 27 public String toString() { 28 return "base:" + base + "t:" + t; 29 } 30 }
t保存节点的有效值,base为节点的状态转移基数
声明字段:
1 private List<Node> states = new ArrayList<>(); 2 private List<Integer> checks = new ArrayList<>();
构造函数:
1 public DoubleArrayTrieTree() { 2 Node root = new Node(); 3 this.states.add(root); 4 }
数组状态变化:
status: states:|0,128,null checks:
只有根节点,检查数组checks为空
字符串插入:
1 @Override 2 public void insert(String str, T t) { 3 if(str != null && str.length() > 0) { 4 byte[] bs = str.getBytes(); 5 int parent = 0; 6 for(byte b : bs) { 7 parent = this.insert(parent, b); 8 } 9 this.states.get(parent).setT(t);; 10 } 11 } 12 13 private int insert(int parent, byte b) { 14 Node parentNode = this.states.get(parent); 15 int parentBase = parentNode.getBase(); 16 int tempChildIndex = parentBase + b; 17 ensureSize(this.states, tempChildIndex); 18 ensureSize(this.checks, tempChildIndex); 19 Integer checkValue = this.checks.get(tempChildIndex); 20 if(checkValue == null) { 21 this.checks.set(tempChildIndex, parent); 22 this.states.set(tempChildIndex, new Node()); 23 }else if (checkValue != parent) { 24 int maxIndex = Integer.MIN_VALUE; 25 List<Integer> children = new LinkedList<>(); 26 for(int i = 0; i < this.checks.size(); i++) { 27 Integer childIndex = this.checks.get(i); 28 if(childIndex != null && childIndex == parent) { 29 children.add(i); 30 if(i > maxIndex) { 31 maxIndex = i; 32 } 33 } 34 } 35 children.add(tempChildIndex); 36 if(tempChildIndex > maxIndex) { 37 maxIndex = tempChildIndex; 38 } 39 int offset = this.ensureCheckValid(children, maxIndex); 40 parentNode.setBase(parentBase + offset); 41 for(int i = 0; i < children.size() - 1; i++) { 42 int originalIndex = children.get(i); 43 this.checks.set(originalIndex + offset, parent); 44 this.states.set(originalIndex + offset, this.states.get(originalIndex)); 45 for(int j = 0; j < this.checks.size(); j++) { 46 Integer originalCheckValue = this.checks.get(j); 47 if(originalCheckValue != null && originalCheckValue == originalIndex) { 48 this.checks.set(j, originalIndex + offset); 49 } 50 } 51 this.checks.set(originalIndex, null); 52 } 53 tempChildIndex = tempChildIndex + offset; 54 this.checks.set(tempChildIndex, parent); 55 this.states.set(tempChildIndex, new Node()); 56 } 57 return tempChildIndex; 58 } 59 60 61 private void ensureSize(List<?> list, int size) { 62 int originalSize = list.size() - 1; 63 if(size > originalSize) { 64 for(int i = 0; i < size - originalSize; i ++) { 65 list.add(null); 66 } 67 } 68 } 69 70 private int ensureCheckValid(List<Integer> list, int maxIndex) { 71 int offset = 0; 72 while(true) { 73 int lastIndex = maxIndex + offset; 74 ensureSize(this.checks, lastIndex); 75 ensureSize(this.states, lastIndex); 76 if(this.checkValid(list, offset)) { 77 break; 78 } 79 offset++; 80 } 81 return offset; 82 } 83 84 85 private boolean checkValid(List<Integer> list, int offset) { 86 for(int originalIndex : list) { 87 if(this.checks.get(originalIndex + offset) != null) { 88 return false; 89 } 90 } 91 return true; 92 }
states数组既要保存数字,也需要保存状态转移的条件,同样需要考虑不同节点存储的碰撞问题
插入字符串:江南大学, 江南, 江边, 南方, 云南 过程中的三数组状态变化:
status: states:|0,128,null|1,null,null|2,null,null|3,null,null|4,null,null|5,null,null|6,null,null|7,null,null|8,null,null|9,null,null|10,null,null|11,null,null|12,null,null|13,128,null|14,null,null|15,null,null|16,null,null|17,null,null|18,null,null|19,null,null|20,null,null|21,null,null|22,null,null|23,130,null|24,null,null|25,null,null|26,null,null|27,null,null|28,null,null|29,null,null|30,null,null|31,128,null|32,null,null|33,null,null|34,null,null|35,null,null|36,128,null|37,null,null|38,128,江南大学|39,131,null|40,null,null|41,null,null|42,null,null|43,null,null|44,null,null|45,128,null|46,null,null|47,null,null|48,null,null|49,128,null|50,null,null|51,null,null|52,null,null|53,null,null|54,null,null|55,null,null|56,null,null|57,null,null|58,null,null|59,null,null|60,null,null|61,null,null|62,null,null|63,null,null|64,null,null|65,null,null|66,null,null|67,null,null|68,null,null|69,null,null|70,null,null|71,null,null|72,null,null|73,null,null|74,null,null|75,null,null|76,null,null|77,null,null|78,null,null|79,null,null|80,null,null|81,null,null|82,null,null|83,null,null|84,null,null|85,null,null|86,null,null|87,null,null|88,null,null|89,null,null|90,null,null|91,null,null|92,null,null|93,null,null|94,null,null|95,null,null|96,null,null|97,null,null|98,null,null|99,null,null|100,null,null|101,128,null|102,128,null|103,128,null|104,128,null checks:|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,101 |14,null |15,null |16,null |17,null |18,null |19,null |20,null |21,null |22,null |23,13 |24,null |25,null |26,null |27,null |28,null |29,null |30,null |31,49 |32,null |33,null |34,null |35,null |36,103 |37,null |38,45 |39,36 |40,null |41,null |42,null |43,null |44,null |45,104 |46,null |47,null |48,null |49,102 |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,31 |102,0 |103,23 |104,39 status: states:|0,128,null|1,null,null|2,null,null|3,null,null|4,null,null|5,null,null|6,null,null|7,null,null|8,null,null|9,null,null|10,null,null|11,null,null|12,null,null|13,128,null|14,null,null|15,null,null|16,null,null|17,null,null|18,null,null|19,null,null|20,null,null|21,null,null|22,null,null|23,130,江南|24,null,null|25,null,null|26,null,null|27,null,null|28,null,null|29,null,null|30,null,null|31,128,null|32,null,null|33,null,null|34,null,null|35,null,null|36,128,null|37,null,null|38,128,江南大学|39,131,null|40,null,null|41,null,null|42,null,null|43,null,null|44,null,null|45,128,null|46,null,null|47,null,null|48,null,null|49,128,null|50,null,null|51,null,null|52,null,null|53,null,null|54,null,null|55,null,null|56,null,null|57,null,null|58,null,null|59,null,null|60,null,null|61,null,null|62,null,null|63,null,null|64,null,null|65,null,null|66,null,null|67,null,null|68,null,null|69,null,null|70,null,null|71,null,null|72,null,null|73,null,null|74,null,null|75,null,null|76,null,null|77,null,null|78,null,null|79,null,null|80,null,null|81,null,null|82,null,null|83,null,null|84,null,null|85,null,null|86,null,null|87,null,null|88,null,null|89,null,null|90,null,null|91,null,null|92,null,null|93,null,null|94,null,null|95,null,null|96,null,null|97,null,null|98,null,null|99,null,null|100,null,null|101,128,null|102,128,null|103,128,null|104,128,null checks:|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,101 |14,null |15,null |16,null |17,null |18,null |19,null |20,null |21,null |22,null |23,13 |24,null |25,null |26,null |27,null |28,null |29,null |30,null |31,49 |32,null |33,null |34,null |35,null |36,103 |37,null |38,45 |39,36 |40,null |41,null |42,null |43,null |44,null |45,104 |46,null |47,null |48,null |49,102 |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,31 |102,0 |103,23 |104,39 status: states:|0,128,null|1,null,null|2,null,null|3,null,null|4,null,null|5,null,null|6,null,null|7,null,null|8,null,null|9,null,null|10,null,null|11,null,null|12,null,null|13,128,null|14,null,null|15,null,null|16,null,null|17,null,null|18,null,null|19,null,null|20,null,null|21,null,null|22,null,null|23,130,江南|24,null,null|25,null,null|26,null,null|27,null,null|28,null,null|29,null,null|30,null,null|31,132,null|32,null,null|33,null,null|34,null,null|35,null,null|36,128,null|37,null,null|38,128,江南大学|39,131,null|40,null,null|41,null,null|42,null,null|43,null,null|44,null,null|45,128,null|46,null,null|47,null,null|48,null,null|49,128,null|50,null,null|51,null,null|52,null,null|53,null,null|54,null,null|55,null,null|56,null,null|57,128,江边|58,null,null|59,null,null|60,null,null|61,null,null|62,128,null|63,null,null|64,null,null|65,null,null|66,null,null|67,null,null|68,null,null|69,null,null|70,null,null|71,null,null|72,null,null|73,null,null|74,null,null|75,null,null|76,null,null|77,null,null|78,null,null|79,null,null|80,null,null|81,null,null|82,null,null|83,null,null|84,null,null|85,null,null|86,null,null|87,null,null|88,null,null|89,null,null|90,null,null|91,null,null|92,null,null|93,null,null|94,null,null|95,null,null|96,null,null|97,null,null|98,null,null|99,null,null|100,null,null|101,128,null|102,128,null|103,128,null|104,128,null|105,128,null|106,null,null|107,null,null|108,128,null checks:|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,105 |14,null |15,null |16,null |17,null |18,null |19,null |20,null |21,null |22,null |23,13 |24,null |25,null |26,null |27,null |28,null |29,null |30,null |31,49 |32,null |33,null |34,null |35,null |36,103 |37,null |38,45 |39,36 |40,null |41,null |42,null |43,null |44,null |45,104 |46,null |47,null |48,null |49,102 |50,null |51,null |52,null |53,null |54,null |55,null |56,null |57,62 |58,null |59,null |60,null |61,null |62,108 |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,23 |104,39 |105,31 |106,null |107,null |108,31 status: states:|0,128,null|1,null,null|2,null,null|3,null,null|4,null,null|5,null,null|6,null,null|7,null,null|8,null,null|9,null,null|10,null,null|11,null,null|12,null,null|13,128,null|14,129,null|15,null,null|16,null,null|17,null,null|18,null,null|19,null,null|20,null,null|21,null,null|22,129,null|23,130,江南|24,132,null|25,null,null|26,null,null|27,null,null|28,null,null|29,null,null|30,null,null|31,132,null|32,null,null|33,null,null|34,null,null|35,null,null|36,128,null|37,null,null|38,128,江南大学|39,131,null|40,null,null|41,null,null|42,null,null|43,null,null|44,null,null|45,128,null|46,null,null|47,null,null|48,null,null|49,128,null|50,null,null|51,null,null|52,null,null|53,null,null|54,null,null|55,null,null|56,null,null|57,128,江边|58,128,南方|59,null,null|60,null,null|61,null,null|62,128,null|63,null,null|64,null,null|65,null,null|66,null,null|67,null,null|68,null,null|69,null,null|70,null,null|71,null,null|72,null,null|73,null,null|74,null,null|75,null,null|76,null,null|77,null,null|78,null,null|79,null,null|80,null,null|81,null,null|82,null,null|83,null,null|84,null,null|85,null,null|86,null,null|87,null,null|88,null,null|89,null,null|90,null,null|91,null,null|92,null,null|93,null,null|94,null,null|95,null,null|96,null,null|97,null,null|98,null,null|99,null,null|100,null,null|101,129,null|102,128,null|103,128,null|104,128,null|105,128,null|106,128,null|107,null,null|108,128,null checks:|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,105 |14,101 |15,null |16,null |17,null |18,null |19,null |20,null |21,null |22,106 |23,13 |24,14 |25,null |26,null |27,null |28,null |29,null |30,null |31,49 |32,null |33,null |34,null |35,null |36,103 |37,null |38,45 |39,36 |40,null |41,null |42,null |43,null |44,null |45,104 |46,null |47,null |48,null |49,102 |50,null |51,null |52,null |53,null |54,null |55,null |56,null |57,62 |58,22 |59,null |60,null |61,null |62,108 |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,23 |104,39 |105,31 |106,24 |107,null |108,31 status: states:|0,128,null|1,null,null|2,null,null|3,null,null|4,null,null|5,null,null|6,null,null|7,null,null|8,null,null|9,null,null|10,null,null|11,null,null|12,null,null|13,128,null|14,129,null|15,130,null|16,null,null|17,134,null|18,null,null|19,null,null|20,null,null|21,null,null|22,129,null|23,130,江南|24,132,null|25,128,云南|26,null,null|27,null,null|28,null,null|29,null,null|30,null,null|31,132,null|32,null,null|33,null,null|34,null,null|35,null,null|36,128,null|37,null,null|38,128,江南大学|39,131,null|40,null,null|41,null,null|42,null,null|43,null,null|44,null,null|45,128,null|46,null,null|47,null,null|48,null,null|49,128,null|50,null,null|51,null,null|52,null,null|53,null,null|54,null,null|55,null,null|56,null,null|57,128,江边|58,128,南方|59,128,null|60,null,null|61,null,null|62,128,null|63,null,null|64,null,null|65,null,null|66,null,null|67,null,null|68,null,null|69,null,null|70,null,null|71,null,null|72,null,null|73,null,null|74,null,null|75,null,null|76,null,null|77,null,null|78,null,null|79,null,null|80,null,null|81,null,null|82,null,null|83,null,null|84,null,null|85,null,null|86,null,null|87,null,null|88,null,null|89,null,null|90,null,null|91,null,null|92,null,null|93,null,null|94,null,null|95,null,null|96,null,null|97,null,null|98,null,null|99,null,null|100,129,null|101,129,null|102,128,null|103,128,null|104,128,null|105,128,null|106,128,null|107,130,null|108,128,null checks:|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,105 |14,101 |15,107 |16,null |17,59 |18,null |19,null |20,null |21,null |22,106 |23,13 |24,14 |25,15 |26,null |27,null |28,null |29,null |30,null |31,49 |32,null |33,null |34,null |35,null |36,103 |37,null |38,45 |39,36 |40,null |41,null |42,null |43,null |44,null |45,104 |46,null |47,null |48,null |49,102 |50,null |51,null |52,null |53,null |54,null |55,null |56,null |57,62 |58,22 |59,100 |60,null |61,null |62,108 |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,23 |104,39 |105,31 |106,24 |107,17 |108,31
字符串查询:
@Override public T search(String str) { if(str != null && str.length() > 0) { byte[] bs = str.getBytes(); int parent = 0; for(byte b : bs) { parent = this.search(parent, b); } if(parent >= 0) { Node node = this.states.get(parent); if(node != null) { return node.getT(); } } } return null; } private int search(int parent, byte b) { if(parent >= 0 && parent < this.states.size()) { Node parentNode = this.states.get(parent); int childIndex = parentNode.getBase() + b; Integer checkValue = this.checks.get(childIndex); if(checkValue != null && checkValue == parent) { return childIndex; } } return -1; }
查询逻辑比较简单
前缀查询:
@Override public List<T> prefixSearch(String prefix) { List<T> result = new LinkedList<>(); if(prefix != null && prefix.length() > 0) { byte[] bs = prefix.getBytes(); int parent = 0; for(int i = 0; i < bs.length; i++) { parent = this.search(parent, bs[i]); } if(parent > 0) { List<Integer> q = new LinkedList<>(); q.add(parent); while (q.size() > 0) { int head = q.remove(0); T t = this.states.get(head).getT(); if(t != null) { result.add(t); } for(int i = 0; i < this.checks.size(); i++) { Integer checkValue = this.checks.get(i); if(checkValue != null && checkValue == head) { q.add(i); } } } } } return result; }
使用队列的方式,遍历前缀查询
3、总结
DoubleArrayTrieTree相对于TripleArrayTrieTree少了一个数组,内存开销进一步减少
参考: https://github.com/pythonerleilei/Search/blob/master/src/seach/data_structure/tree/impl/DoubleArrayTrieTree.java
以上是关于Trie树_5-DoubleArrayTrieTree的主要内容,如果未能解决你的问题,请参考以下文章