1. 程式人生 > >自定義字典樹(字首樹)

自定義字典樹(字首樹)

通過學習自定義字典樹,瞭解字典樹這一資料結構。

 

之前的二分搜尋樹(二叉樹)堆(完全二叉樹)線段樹(平衡二叉樹)都是基於二叉樹。而字典樹是一種多叉樹。

 

 

如果有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;
	}
	
	
	
	
	
	
	
	
	
	
	
	
}