数据结构之字典树,前缀树(Trie)

字典树是多叉树,通常用于处理字符串,如存储单词等

字典树的实现

1. 基本类的实现

public class Trie {
	private class Node{
		//指向子结点
		public TreeMap<Character,Node> next;  
		public boolean isWord;
		
		public Node(boolean isWord) {
			this.isWord = isWord;
			next= new TreeMap<>();
		}
		
		public Node() {
			this(false);
		}
	}
	
	private Node root;  //Trie树的根结点
	private int size;   //树中结点个数
	
	public Trie() {
		root = new Node();
		size = 0;
	}
	
	public int getSize() {
		return size;
	}
}

2. 向字典树中添加单词

//向字典树中添加单词
	public void add(String str) {
		Node current = root;
		
		//依次添加str的每一个字母
		for(int i = 0; i < str.length(); ++i) {
			char ch = str.charAt(i);
			
			//映射中不包含键值为ch的条目,则将键值为ch的条目插入其中
			if(current.next.get(ch) == null) {
				current.next.put(ch,new Node());
			}
			//将current指向当前结点的满足条件(键值为ch)的孩子结点
			current = current.next.get(ch);
		}
		
		/*
		 * 更新size大小时需要考虑到前缀问题
		 * 1. 当遍历完传入的单词str时,可能并为到达树中一个单词的结尾
		 * 	  如 str = "pan",Trie中存的是 "panda"
		 * 2. 如果current执行的结点的isWord为false,说明树中还没有存入
		 *   pan这个单词,此时应将n结点的isWord更改为true,并更新size
		 * 3. size指的是树中单词的个数(前缀单词也是单词:pan 和 panda是两个单词)
		 */
		if(!current.isWord) {
			current.isWord = true;
			size++;
		}
	}

3. 查询某一单词是否在字典树中

    /*		
	 * 判断某一单词是否在字典树中
	 * 方法:1. 依次获取单词的每一个字母,作为键值去映射中查找是否有
	 *	          与之对应的条目,若有则进行下一个字母的比对,没有则返回false
	 *	          直至最后一个字母。
	 *		2. 若对单词str遍历完成未发现不匹配的条目,则对current结点的
	 *		  isWord进行判断,若其值为true,说明这是一个前缀单词,且已经
	 *		  存入到当前字典树中,返回true,反之返回false。
	 */
	public boolean contains(String str) {
		Node current = root;
		
		for(int i = 0; i < str.length(); ++i) {
			char ch = str.charAt(i);
			
			if(current.next.get(ch) == null)
				return false;
			current = current.next.get(ch);
		}
		
		return current.isWord;
	}

4. 判断某一字符串是否为字典树中单词的前缀

    /*
	 * 		判断某一字符串时候是单词的前缀(不要求prefix是单词)
	 * 方法(大致思路和contains一致):
	 * 	1.  依次获取字符串prefix的每一个字母,作为键值去映射中查找是否有
	 * 	     与之对应的条目,若有则进行下一个字母的比对,没有则返回false
	 * 	     直至最后一个字母。
	 *  2. 如果循环比对之后为发现不匹配的条目,说明prefix是一个前缀,返回true
	 */
	public boolean isPrefix(String prefix) {
		Node current = root;
		for(int i = 0; i < prefix.length(); ++i) {
			char ch = prefix.charAt(i);
			if(current.next.get(ch) == null)
				return false;
			current = current.next.get(ch);
		}
		return true;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值