自定义字典树(前缀树)

版权声明:转载请注明出处: https://blog.csdn.net/qq_34774655/article/details/85685913

通过学习自定义字典树,了解字典树这一数据结构。

之前的二分搜索树(二叉树)堆(完全二叉树)线段树(平衡二叉树)都是基于二叉树。而字典树是一种多叉树。

 

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

 

猜你喜欢

转载自blog.csdn.net/qq_34774655/article/details/85685913