Trie樹的原理html
Trie樹也稱字典樹,由於其效率很高,因此在在字符串查找、前綴匹配等中應用很普遍,其高效率是以空間爲代價的。this
利用串構建一個字典樹,這個字典樹保存了串的公共前綴信息,所以能夠下降查詢操做的複雜度。下面以英文單詞構建的字典樹爲例,這棵Trie樹中每一個結點包括26個孩子結點,由於總共有26個英文字母(假設單詞都是小寫字母組成)。spa
詳細介紹請參考:http://www.cnblogs.com/dolphin0520/archive/2011/10/11/2207886.html 等指針
字典樹模版(Java)code
1 /** 2 * 字典樹模版,默認只包含26個小寫字母 3 * 提供hasStr、insert、countPrefix、preWalk、getRoot接口 4 * @author 5 */ 6 public class TrieTree { 7 8 private final int SIZE = 26; //每一個節點能包含的子節點數,即須要SIZE個指針來指向其孩子 9 private Node root; //字典樹的根節點 10 11 /** 12 * 字典樹節點類 13 * @author Lenovo 14 */ 15 private class Node { 16 private boolean isStr; //標識該節點是否爲某一字符串終端節點 17 private int num; //標識通過該節點的字符串數。在計算前綴包含的時候會用到 18 private Node[] child; //該節點的子節點 19 20 public Node() { 21 child = new Node[SIZE]; 22 isStr = false; 23 num = 1; 24 } 25 } 26 27 public TrieTree() { 28 root = new Node(); 29 } 30 31 /** 32 * 檢查字典樹中是否徹底包含字符串word 33 * @param word 34 * @return 35 */ 36 public boolean hasStr(String word) { 37 Node pNode = this.root; 38 39 //逐個字符去檢查 40 for (int i = 0; i < word.length(); i++) { 41 int index = word.charAt(i) - 'a'; 42 //在字典樹中沒有對應的節點,或者word字符串的最後一個字符在字典樹中檢測對應節點的isStr屬性爲false,則返回false 43 if (pNode.child[index] == null 44 || (i + 1 == word.length() && pNode.child[index].isStr == false)) { 45 return false; 46 } 47 pNode = pNode.child[index]; 48 } 49 50 return true; 51 } 52 53 /** 54 * 在字典樹中插入一個單詞 55 * @param word 56 */ 57 public void insert(String word) { 58 if (word == null || word.isEmpty()) { 59 return; 60 } 61 Node pNode = this.root; 62 for (int i = 0; i < word.length(); i++) { 63 int index = word.charAt(i) - 'a'; 64 if (pNode.child[index] == null) { //若是不存在節點,則new一個一節點插入字典樹 65 Node tmpNode = new Node(); 66 pNode.child[index] = tmpNode; 67 } else { 68 pNode.child[index].num++; //若是字典樹中改路徑上存在節點,則num加1,表示在該節點上有一個新的單詞通過 69 } 70 pNode = pNode.child[index]; 71 } 72 pNode.isStr = true; 73 } 74 75 /** 76 * 統計在字典樹中有多少個單詞是以str爲前綴的 77 * @param str 78 * @return 79 */ 80 public int countPrefix(String str) { 81 Node pNode = this.root; 82 for (int i = 0; i < str.length(); i++) { 83 int index = str.charAt(i) - 'a'; 84 if (pNode.child[index] == null) { 85 return 0; 86 } else { 87 pNode = pNode.child[index]; 88 } 89 } 90 91 return pNode.num; 92 } 93 94 /** 95 * 先序遍歷 96 * @param root 97 */ 98 public void preWalk(Node root) { 99 Node pNode = root; 100 for (int i = 0; i < SIZE; i++) { 101 if (pNode.child[i] != null) { 102 System.out.print((char) ('a' + i) + "--"); 103 preWalk(pNode.child[i]); 104 } 105 } 106 } 107 108 /** 109 * 返回字典樹根節點 110 * @return 111 */ 112 public Node getRoot() { 113 return root; 114 } 115 116 }