字典樹Java實現


Trie樹的原理

  Trie樹也稱字典樹,因為其效率很高,所以在在字符串查找、前綴匹配等中應用很廣泛,其高效率是以空間為代價的。

  利用串構建一個字典樹,這個字典樹保存了串的公共前綴信息,因此可以降低查詢操作的復雜度。下面以英文單詞構建的字典樹為例,這棵Trie樹中每個結點包括26個孩子結點,因為總共有26個英文字母(假設單詞都是小寫字母組成)。

詳細介紹請參考:http://www.cnblogs.com/dolphin0520/archive/2011/10/11/2207886.html 等

字典樹模版(Java)

  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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM