自定義字典樹(字首樹)
阿新 • • 發佈:2019-01-03
通過學習自定義字典樹,瞭解字典樹這一資料結構。
之前的二分搜尋樹(二叉樹)、堆(完全二叉樹)、線段樹(平衡二叉樹)都是基於二叉樹。而字典樹是一種多叉樹。
如果有n個條目,使用樹結構查詢的時間複雜度為O(log n),如果有100萬個條目(2^20),log n 大約為20; 而使用Trie(字典樹)的時間複雜度與有多少條目無關,為O(w),w為查詢單詞的長度(大多數單詞的長度不超過10)。
Trie的侷限性:空間問題。
實踐:字首搜尋 參考208
實踐:簡單的模式匹配 參考211
實踐:Trie和對映 參考611
自定義字典樹(Trie):
package Trie; import java.util.TreeMap;//java提供的TreeMap底層是紅黑樹 public class Trie { /** * 內部類 * * @author xiaohau * */ private class Node{ public boolean isWord;//指示當前node是否為一個完整的單詞 public TreeMap<Character,Node> next;//儲存字元及下一個節點資訊 public Node(boolean isWord) { this.isWord=isWord; next=new TreeMap<>(); } public Node() { this(false); } } private Node root;//根節點 private int size;//字典樹中單詞數量 /** * 無參建構函式,初始化根節點 */ public Trie() { root=new Node(); size=0; } /** * 返回字典樹中單詞的數量 * @return */ public int getSize() { return size; } /** * 向Trie中新增一個新的單詞word * @param word */ public void add(String word) { Node cur=root;//指向當前頭結點 //遍歷單詞每個字元,若節點中不存在,則新增,負責,跳過該結點,繼續判斷 for(int i=0;i<word.length();i++) { char c=word.charAt(i); if(cur.next.get(c)==null) { cur.next.put(c, new Node()); } cur=cur.next.get(c); } //修改當前結點為一個完整的單詞 if(!cur.isWord) { cur.isWord=true; size++; } } /** * 查詢單詞word是否在Trie中 * @param word * @return */ public boolean contains(String word) { Node cur=root; for(int i=0;i<word.length();i++) { char c=word.charAt(i); if(cur.next.get(c)==null) { return false; } cur=cur.next.get(c); } return cur.isWord; } /** * 查詢是否在Trie中有單詞以prefix為字首 * 注:整個單詞也是整個單詞的字首 * @param prefix * @return */ public boolean isPrefix(String prefix) { Node cur=root; for(int i=0;i<prefix.length();i++) { char c=prefix.charAt(i); if(cur.next.get(c)==null) { return false; } cur=cur.next.get(c); } return true; } }